formtastic 3.1.1 → 4.0.0.rc1

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