formtastic 3.1.3 → 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 (179) hide show
  1. checksums.yaml +7 -0
  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} +183 -167
  9. data/RELEASE_PROCESS +3 -1
  10. data/Rakefile +20 -1
  11. data/app/assets/stylesheets/formtastic.css +1 -1
  12. data/bin/appraisal +8 -0
  13. data/formtastic.gemspec +12 -16
  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 +1 -0
  20. data/lib/formtastic/actions/base.rb +1 -0
  21. data/lib/formtastic/actions/button_action.rb +1 -0
  22. data/lib/formtastic/actions/buttonish.rb +1 -0
  23. data/lib/formtastic/actions/input_action.rb +1 -0
  24. data/lib/formtastic/actions/link_action.rb +1 -0
  25. data/lib/formtastic/actions.rb +7 -3
  26. data/lib/formtastic/deprecation.rb +2 -38
  27. data/lib/formtastic/engine.rb +4 -1
  28. data/lib/formtastic/form_builder.rb +12 -24
  29. data/lib/formtastic/helpers/action_helper.rb +2 -48
  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 +14 -9
  34. data/lib/formtastic/helpers/file_column_detection.rb +1 -0
  35. data/lib/formtastic/helpers/form_helper.rb +2 -1
  36. data/lib/formtastic/helpers/input_helper.rb +20 -76
  37. data/lib/formtastic/helpers/inputs_helper.rb +29 -23
  38. data/lib/formtastic/helpers/reflection.rb +1 -0
  39. data/lib/formtastic/helpers.rb +2 -2
  40. data/lib/formtastic/html_attributes.rb +1 -0
  41. data/lib/formtastic/i18n.rb +2 -1
  42. data/lib/formtastic/input_class_finder.rb +1 -0
  43. data/lib/formtastic/inputs/base/associations.rb +1 -0
  44. data/lib/formtastic/inputs/base/choices.rb +3 -2
  45. data/lib/formtastic/inputs/base/collections.rb +46 -10
  46. data/lib/formtastic/inputs/base/database.rb +5 -7
  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 +9 -7
  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 +1 -0
  61. data/lib/formtastic/inputs/base.rb +3 -2
  62. data/lib/formtastic/inputs/boolean_input.rb +2 -1
  63. data/lib/formtastic/inputs/check_boxes_input.rb +15 -6
  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 +1 -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 +1 -0
  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 +21 -0
  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 +30 -1
  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 -29
  88. data/lib/formtastic/localized_string.rb +1 -0
  89. data/lib/formtastic/localizer.rb +21 -22
  90. data/lib/formtastic/namespaced_class_finder.rb +8 -9
  91. data/lib/formtastic/version.rb +2 -1
  92. data/lib/formtastic.rb +10 -11
  93. data/lib/generators/formtastic/form/form_generator.rb +2 -1
  94. data/lib/generators/formtastic/input/input_generator.rb +47 -0
  95. data/lib/generators/formtastic/install/install_generator.rb +1 -0
  96. data/lib/generators/templates/formtastic.rb +15 -13
  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 +2 -1
  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 +329 -10
  114. data/spec/helpers/actions_helper_spec.rb +43 -42
  115. data/spec/helpers/form_helper_spec.rb +45 -38
  116. data/spec/helpers/input_helper_spec.rb +976 -2
  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 +2 -1
  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 +169 -121
  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 +3 -2
  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 +26 -25
  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 +18 -6
  157. data/spec/schema.rb +22 -0
  158. data/spec/spec_helper.rb +172 -260
  159. data/spec/support/custom_macros.rb +74 -76
  160. data/spec/support/deprecation.rb +2 -1
  161. data/spec/support/shared_examples.rb +2 -1233
  162. data/spec/support/specialized_class_finder_shared_example.rb +1 -0
  163. data/spec/support/test_environment.rb +24 -9
  164. metadata +78 -170
  165. data/.travis.yml +0 -29
  166. data/Appraisals +0 -29
  167. data/CHANGELOG +0 -39
  168. data/DEPRECATIONS +0 -49
  169. data/gemfiles/rails_3.2.gemfile +0 -7
  170. data/gemfiles/rails_4.0.4.gemfile +0 -7
  171. data/gemfiles/rails_4.1.gemfile +0 -7
  172. data/gemfiles/rails_4.2.gemfile +0 -7
  173. data/gemfiles/rails_4.gemfile +0 -7
  174. data/gemfiles/rails_edge.gemfile +0 -10
  175. data/lib/formtastic/util.rb +0 -57
  176. data/spec/helpers/namespaced_action_helper_spec.rb +0 -43
  177. data/spec/helpers/namespaced_input_helper_spec.rb +0 -36
  178. data/spec/support/deferred_garbage_collection.rb +0 -21
  179. data/spec/util_spec.rb +0 -66
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ require 'generators/formtastic/input/input_generator'
5
+
6
+ RSpec.describe Formtastic::InputGenerator do
7
+ include FormtasticSpecHelper
8
+
9
+ destination File.expand_path("../../../../../tmp", __FILE__)
10
+
11
+ before do
12
+ prepare_destination
13
+ end
14
+
15
+ after do
16
+ FileUtils.rm_rf(File.expand_path("../../../../../tmp", __FILE__))
17
+ end
18
+
19
+ describe 'without file name' do
20
+ it 'should raise Thor::RequiredArgumentMissingError' do
21
+ expect { run_generator }.to raise_error(Thor::RequiredArgumentMissingError)
22
+ end
23
+ end
24
+
25
+ describe "input generator with underscore definition" do
26
+ before { run_generator %w(hat_size)}
27
+
28
+ describe 'generate an input in its respective folder' do
29
+ subject{ file('app/inputs/hat_size_input.rb')}
30
+ it { is_expected.to exist}
31
+ it { is_expected.to contain "class HatSizeInput"}
32
+ it { is_expected.to contain "def to_html"}
33
+ it { is_expected.to contain "include Formtastic::Inputs::Base"}
34
+ it { is_expected.not_to contain "super"}
35
+ end
36
+ end
37
+
38
+ describe "input generator with camelcase definition" do
39
+ before { run_generator %w(HatSize)}
40
+
41
+ describe 'generate an input in its respective folder' do
42
+ subject{ file('app/inputs/hat_size_input.rb')}
43
+ it { is_expected.to exist}
44
+ it { is_expected.to contain "class HatSizeInput"}
45
+ end
46
+ end
47
+
48
+ describe "input generator with camelcase Input name sufixed" do
49
+ before { run_generator %w(HatSizeInput)}
50
+
51
+ describe 'generate an input in its respective folder' do
52
+ subject{ file('app/inputs/hat_size_input.rb')}
53
+ it { is_expected.to exist}
54
+ it { is_expected.to contain "class HatSizeInput"}
55
+ end
56
+ end
57
+
58
+ describe "input generator with underscore _input name sufixed" do
59
+ before { run_generator %w(hat_size_input)}
60
+
61
+ describe 'generate an input in its respective folder' do
62
+ subject{ file('app/inputs/hat_size_input.rb')}
63
+ it { is_expected.to exist}
64
+ it { is_expected.to contain "class HatSizeInput"}
65
+ end
66
+ end
67
+
68
+ describe "input generator with underscore input name sufixed" do
69
+ before { run_generator %w(hat_sizeinput)}
70
+
71
+ describe 'generate an input in its respective folder' do
72
+ subject{ file('app/inputs/hat_size_input.rb')}
73
+ it { is_expected.to exist}
74
+ it { is_expected.to contain "class HatSizeInput"}
75
+ end
76
+ end
77
+
78
+ describe "override an existing input using extend" do
79
+ before { run_generator %w(string --extend)}
80
+
81
+ describe 'app/inputs/string_input.rb' do
82
+ subject{ file('app/inputs/string_input.rb')}
83
+ it { is_expected.to exist }
84
+ it { is_expected.to contain "class StringInput < Formtastic::Inputs::StringInput" }
85
+ it { is_expected.to contain "def to_html" }
86
+ it { is_expected.not_to contain "include Formtastic::Inputs::Base" }
87
+ it { is_expected.to contain "super" }
88
+ it { is_expected.not_to contain "def input_html_options" }
89
+ end
90
+ end
91
+
92
+ describe "extend an existing input" do
93
+ before { run_generator %w(FlexibleText --extend string)}
94
+
95
+ describe 'app/inputs/flexible_text_input.rb' do
96
+ subject{ file('app/inputs/flexible_text_input.rb')}
97
+ it { is_expected.to contain "class FlexibleTextInput < Formtastic::Inputs::StringInput" }
98
+ it { is_expected.to contain "def input_html_options" }
99
+ it { is_expected.not_to contain "include Formtastic::Inputs::Base" }
100
+ it { is_expected.not_to contain "def to_html" }
101
+ end
102
+ end
103
+
104
+ describe "provide a slashed namespace" do
105
+ before { run_generator %w(stuff/foo)}
106
+
107
+ describe 'app/inputs/stuff/foo_input.rb' do
108
+ subject{ file('app/inputs/stuff/foo_input.rb')}
109
+ it {is_expected.to exist}
110
+ it { is_expected.to contain "class Stuff::FooInput" }
111
+ it { is_expected.to contain "include Formtastic::Inputs::Base" }
112
+ end
113
+ end
114
+
115
+ describe "provide a camelized namespace" do
116
+ before { run_generator %w(Stuff::Foo)}
117
+
118
+ describe 'app/inputs/stuff/foo_input.rb' do
119
+ subject{ file('app/inputs/stuff/foo_input.rb')}
120
+ it {is_expected.to exist}
121
+ it { is_expected.to contain "class Stuff::FooInput" }
122
+ it { is_expected.to contain "include Formtastic::Inputs::Base" }
123
+ end
124
+ end
125
+ end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  # Generators are not automatically loaded by Rails
4
5
  require 'generators/formtastic/install/install_generator'
5
6
 
6
- describe Formtastic::InstallGenerator do
7
+ RSpec.describe Formtastic::InstallGenerator do
7
8
  # Tell the generator where to put its output (what it thinks of as Rails.root)
8
9
  destination File.expand_path("../../../../../tmp", __FILE__)
9
10
 
@@ -14,14 +15,14 @@ describe Formtastic::InstallGenerator do
14
15
 
15
16
  describe 'config/initializers/formtastic.rb' do
16
17
  subject { file('config/initializers/formtastic.rb') }
17
- it { should exist }
18
- it { should contain "#" }
18
+ it { is_expected.to exist }
19
+ it { is_expected.to contain "#" }
19
20
  end
20
21
 
21
22
  describe 'lib/templates/erb/scaffold/_form.html.erb' do
22
23
  subject { file('lib/templates/erb/scaffold/_form.html.erb') }
23
- it { should exist }
24
- it { should contain "<%%= semantic_form_for @<%= singular_name %> do |f| %>" }
24
+ it { is_expected.to exist }
25
+ it { is_expected.to contain "<%%= semantic_form_for @<%= singular_name %> do |f| %>" }
25
26
  end
26
27
  end
27
28
 
@@ -30,8 +31,8 @@ describe Formtastic::InstallGenerator do
30
31
 
31
32
  describe 'lib/templates/erb/scaffold/_form.html.haml' do
32
33
  subject { file('lib/templates/haml/scaffold/_form.html.haml') }
33
- it { should exist }
34
- it { should contain "= semantic_form_for @<%= singular_name %> do |f|" }
34
+ it { is_expected.to exist }
35
+ it { is_expected.to contain "= semantic_form_for @<%= singular_name %> do |f|" }
35
36
  end
36
37
  end
37
38
 
@@ -40,8 +41,8 @@ describe Formtastic::InstallGenerator do
40
41
 
41
42
  describe 'lib/templates/erb/scaffold/_form.html.slim' do
42
43
  subject { file('lib/templates/slim/scaffold/_form.html.slim') }
43
- it { should exist }
44
- it { should contain "= semantic_form_for @<%= singular_name %> do |f|" }
44
+ it { is_expected.to exist }
45
+ it { is_expected.to contain "= semantic_form_for @<%= singular_name %> do |f|" }
45
46
  end
46
47
  end
47
48
  end
@@ -1,19 +1,338 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
  require 'spec_helper'
3
3
 
4
- describe 'Formtastic::FormBuilder#action' do
5
- include_context 'Action Helper' # from spec/support/shared_examples.rb
4
+ RSpec.describe 'with action class finder' do
5
+ include_context 'form builder'
6
+
7
+ describe 'arguments and options' do
8
+
9
+ it 'should require the first argument (the action method)' do
10
+ expect {
11
+ concat(semantic_form_for(@new_post) do |builder|
12
+ concat(builder.action()) # no args passed in at all
13
+ end)
14
+ }.to raise_error(ArgumentError)
15
+ end
16
+
17
+ describe ':as option' do
18
+
19
+ describe 'when not provided' do
20
+
21
+ it 'should default to a commit for commit' do
22
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
23
+ concat(builder.action(:submit))
24
+ end)
25
+ expect(output_buffer.to_str).to have_tag('form li.action.input_action', :count => 1)
26
+ end
27
+
28
+ it 'should default to a button for reset' do
29
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
30
+ concat(builder.action(:reset))
31
+ end)
32
+ expect(output_buffer.to_str).to have_tag('form li.action.input_action', :count => 1)
33
+ end
34
+
35
+ it 'should default to a link for cancel' do
36
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
37
+ concat(builder.action(:cancel))
38
+ end)
39
+ expect(output_buffer.to_str).to have_tag('form li.action.link_action', :count => 1)
40
+ end
41
+ end
42
+
43
+ it 'should call the corresponding action class with .to_html' do
44
+ [:input, :button, :link].each do |action_style|
45
+ semantic_form_for(:project, :url => "http://test.host") do |builder|
46
+ action_instance = double('Action instance')
47
+ action_class = "#{action_style.to_s}_action".classify
48
+ action_constant = "Formtastic::Actions::#{action_class}".constantize
49
+
50
+ expect(action_constant).to receive(:new).and_return(action_instance)
51
+ expect(action_instance).to receive(:to_html).and_return("some HTML")
52
+
53
+ concat(builder.action(:submit, :as => action_style))
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ #describe ':label option' do
61
+ #
62
+ # describe 'when provided' do
63
+ # it 'should be passed down to the label tag' do
64
+ # concat(semantic_form_for(@new_post) do |builder|
65
+ # concat(builder.input(:title, :label => "Kustom"))
66
+ # end)
67
+ # output_buffer.should have_tag("form li label", /Kustom/)
68
+ # end
69
+ #
70
+ # it 'should not generate a label if false' do
71
+ # concat(semantic_form_for(@new_post) do |builder|
72
+ # concat(builder.input(:title, :label => false))
73
+ # end)
74
+ # output_buffer.should_not have_tag("form li label")
75
+ # end
76
+ #
77
+ # it 'should be dupped if frozen' do
78
+ # concat(semantic_form_for(@new_post) do |builder|
79
+ # concat(builder.input(:title, :label => "Kustom".freeze))
80
+ # end)
81
+ # output_buffer.should have_tag("form li label", /Kustom/)
82
+ # end
83
+ # end
84
+ #
85
+ # describe 'when not provided' do
86
+ # describe 'when localized label is provided' do
87
+ # describe 'and object is given' do
88
+ # describe 'and label_str_method not :humanize' do
89
+ # it 'should render a label with localized text and not apply the label_str_method' do
90
+ # with_config :label_str_method, :reverse do
91
+ # @localized_label_text = 'Localized title'
92
+ # @new_post.stub(:meta_description)
93
+ # ::I18n.backend.store_translations :en,
94
+ # :formtastic => {
95
+ # :labels => {
96
+ # :meta_description => @localized_label_text
97
+ # }
98
+ # }
99
+ #
100
+ # concat(semantic_form_for(@new_post) do |builder|
101
+ # concat(builder.input(:meta_description))
102
+ # end)
103
+ # output_buffer.should have_tag('form li label', /Localized title/)
104
+ # end
105
+ # end
106
+ # end
107
+ # end
108
+ # end
109
+ #
110
+ # describe 'when localized label is NOT provided' do
111
+ # describe 'and object is not given' do
112
+ # it 'should default the humanized method name, passing it down to the label tag' do
113
+ # ::I18n.backend.store_translations :en, :formtastic => {}
114
+ # with_config :label_str_method, :humanize do
115
+ # concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
116
+ # concat(builder.input(:meta_description))
117
+ # end)
118
+ # output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
119
+ # end
120
+ # end
121
+ # end
122
+ #
123
+ # describe 'and object is given' do
124
+ # it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
125
+ # @new_post.stub(:meta_description) # a two word method name
126
+ # @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
127
+ #
128
+ # concat(semantic_form_for(@new_post) do |builder|
129
+ # concat(builder.input(:meta_description))
130
+ # end)
131
+ # output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
132
+ # end
133
+ # end
134
+ #
135
+ # describe 'and object is given with label_str_method set to :capitalize' do
136
+ # it 'should capitalize method name, passing it down to the label tag' do
137
+ # with_config :label_str_method, :capitalize do
138
+ # @new_post.stub(:meta_description)
139
+ #
140
+ # concat(semantic_form_for(@new_post) do |builder|
141
+ # concat(builder.input(:meta_description))
142
+ # end)
143
+ # output_buffer.should have_tag("form li label", /#{'meta_description'.capitalize}/)
144
+ # end
145
+ # end
146
+ # end
147
+ # end
148
+ #
149
+ # describe 'when localized label is provided' do
150
+ # before do
151
+ # @localized_label_text = 'Localized title'
152
+ # @default_localized_label_text = 'Default localized title'
153
+ # ::I18n.backend.store_translations :en,
154
+ # :formtastic => {
155
+ # :labels => {
156
+ # :title => @default_localized_label_text,
157
+ # :published => @default_localized_label_text,
158
+ # :post => {
159
+ # :title => @localized_label_text,
160
+ # :published => @default_localized_label_text
161
+ # }
162
+ # }
163
+ # }
164
+ # end
165
+ #
166
+ # it 'should render a label with localized label (I18n)' do
167
+ # with_config :i18n_lookups_by_default, false do
168
+ # concat(semantic_form_for(@new_post) do |builder|
169
+ # concat(builder.input(:title, :label => true))
170
+ # concat(builder.input(:published, :as => :boolean, :label => true))
171
+ # end)
172
+ # output_buffer.should have_tag('form li label', Regexp.new('^' + @localized_label_text))
173
+ # end
174
+ # end
175
+ #
176
+ # it 'should render a hint paragraph containing an optional localized label (I18n) if first is not set' do
177
+ # with_config :i18n_lookups_by_default, false do
178
+ # ::I18n.backend.store_translations :en,
179
+ # :formtastic => {
180
+ # :labels => {
181
+ # :post => {
182
+ # :title => nil,
183
+ # :published => nil
184
+ # }
185
+ # }
186
+ # }
187
+ # concat(semantic_form_for(@new_post) do |builder|
188
+ # concat(builder.input(:title, :label => true))
189
+ # concat(builder.input(:published, :as => :boolean, :label => true))
190
+ # end)
191
+ # output_buffer.should have_tag('form li label', Regexp.new('^' + @default_localized_label_text))
192
+ # end
193
+ # end
194
+ # end
195
+ # end
196
+ #
197
+ #end
198
+ #
199
+ describe ':wrapper_html option' do
200
+
201
+ describe 'when provided' do
202
+ it 'should be passed down to the li tag' do
203
+ concat(semantic_form_for(@new_post) do |builder|
204
+ concat(builder.action(:submit, :wrapper_html => {:id => :another_id}))
205
+ end)
206
+ expect(output_buffer.to_str).to have_tag("form li#another_id")
207
+ end
208
+
209
+ it 'should append given classes to li default classes' do
210
+ concat(semantic_form_for(@new_post) do |builder|
211
+ concat(builder.action(:submit, :wrapper_html => {:class => :another_class}))
212
+ end)
213
+ expect(output_buffer.to_str).to have_tag("form li.action")
214
+ expect(output_buffer.to_str).to have_tag("form li.input_action")
215
+ expect(output_buffer.to_str).to have_tag("form li.another_class")
216
+ end
217
+
218
+ it 'should allow classes to be an array' do
219
+ concat(semantic_form_for(@new_post) do |builder|
220
+ concat(builder.action(:submit, :wrapper_html => {:class => [ :my_class, :another_class ]}))
221
+ end)
222
+ expect(output_buffer.to_str).to have_tag("form li.action")
223
+ expect(output_buffer.to_str).to have_tag("form li.input_action")
224
+ expect(output_buffer.to_str).to have_tag("form li.my_class")
225
+ expect(output_buffer.to_str).to have_tag("form li.another_class")
226
+ end
227
+ end
228
+
229
+ describe 'when not provided' do
230
+ it 'should use default id and class' do
231
+ concat(semantic_form_for(@new_post) do |builder|
232
+ concat(builder.action(:submit))
233
+ end)
234
+ expect(output_buffer.to_str).to have_tag("form li#post_submit_action")
235
+ expect(output_buffer.to_str).to have_tag("form li.action")
236
+ expect(output_buffer.to_str).to have_tag("form li.input_action")
237
+ end
238
+ end
239
+
240
+ end
241
+
242
+ end
6
243
 
7
- # TODO: remove this in Formtastic 4.0
8
244
  describe 'instantiating an action class' do
9
- context 'of unknown action' do
10
- it "should try to load class named as the action" do
245
+ context 'when a class does not exist' do
246
+ it "should raise an error" do
11
247
  expect {
12
- semantic_form_for(@new_post) do |builder|
13
- builder.action(:destroy)
14
- end
15
- }.to raise_error(Formtastic::UnknownActionError, 'Unable to find action destroy')
248
+ concat(semantic_form_for(@new_post) do |builder|
249
+ builder.action(:submit, :as => :non_existant)
250
+ end)
251
+ }.to raise_error(Formtastic::UnknownActionError)
16
252
  end
17
253
  end
254
+
255
+ context 'when a customized top-level class does not exist' do
256
+ it 'should instantiate the Formtastic action' do
257
+ action = double('action', :to_html => 'some HTML')
258
+ expect(Formtastic::Actions::ButtonAction).to receive(:new).and_return(action)
259
+ concat(semantic_form_for(@new_post) do |builder|
260
+ builder.action(:commit, :as => :button)
261
+ end)
262
+ end
263
+ end
264
+
265
+ describe 'when a top-level (custom) action class exists' do
266
+ it "should instantiate the top-level action instead of the Formtastic one" do
267
+ class ::ButtonAction < Formtastic::Actions::ButtonAction
268
+ end
269
+
270
+ action = double('action', :to_html => 'some HTML')
271
+ expect(Formtastic::Actions::ButtonAction).not_to receive(:new)
272
+ expect(::ButtonAction).to receive(:new).and_return(action)
273
+
274
+ concat(semantic_form_for(@new_post) do |builder|
275
+ builder.action(:commit, :as => :button)
276
+ end)
277
+ end
278
+ end
279
+
280
+ describe 'support for :as on each action' do
281
+
282
+ it "should raise an error when the action does not support the :as" do
283
+ expect {
284
+ concat(semantic_form_for(@new_post) do |builder|
285
+ concat(builder.action(:submit, :as => :link))
286
+ end)
287
+ }.to raise_error(Formtastic::UnsupportedMethodForAction)
288
+
289
+ expect {
290
+ concat(semantic_form_for(@new_post) do |builder|
291
+ concat(builder.action(:cancel, :as => :input))
292
+ end)
293
+ }.to raise_error(Formtastic::UnsupportedMethodForAction)
294
+
295
+ expect {
296
+ concat(semantic_form_for(@new_post) do |builder|
297
+ concat(builder.action(:cancel, :as => :button))
298
+ end)
299
+ }.to raise_error(Formtastic::UnsupportedMethodForAction)
300
+ end
301
+
302
+ it "should not raise an error when the action does not support the :as" do
303
+ expect {
304
+ concat(semantic_form_for(@new_post) do |builder|
305
+ concat(builder.action(:cancel, :as => :link))
306
+ end)
307
+ }.not_to raise_error
308
+
309
+ expect {
310
+ concat(semantic_form_for(@new_post) do |builder|
311
+ concat(builder.action(:submit, :as => :input))
312
+ end)
313
+ }.not_to raise_error
314
+
315
+ expect {
316
+ concat(semantic_form_for(@new_post) do |builder|
317
+ concat(builder.action(:submit, :as => :button))
318
+ end)
319
+ }.not_to raise_error
320
+
321
+ expect {
322
+ concat(semantic_form_for(@new_post) do |builder|
323
+ concat(builder.action(:reset, :as => :input))
324
+ end)
325
+ }.not_to raise_error
326
+
327
+ expect {
328
+ concat(semantic_form_for(@new_post) do |builder|
329
+ concat(builder.action(:reset, :as => :button))
330
+ end)
331
+ }.not_to raise_error
332
+ end
333
+
334
+ end
335
+
18
336
  end
337
+
19
338
  end