formtastic 3.1.5 → 4.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitattributes +1 -0
- data/.gitignore +3 -2
- data/.travis.yml +28 -40
- data/CHANGELOG.md +49 -0
- data/DEPRECATIONS +1 -1
- data/Gemfile.lock +104 -0
- data/README.md +628 -629
- data/Rakefile +20 -1
- data/app/assets/stylesheets/formtastic.css +1 -1
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +8 -14
- data/gemfiles/rails_5.2/Gemfile +5 -0
- data/gemfiles/rails_6.0/Gemfile +5 -0
- data/gemfiles/rails_edge/Gemfile +13 -0
- data/lib/formtastic.rb +5 -11
- data/lib/formtastic/actions.rb +6 -3
- data/lib/formtastic/deprecation.rb +1 -38
- data/lib/formtastic/engine.rb +3 -1
- data/lib/formtastic/form_builder.rb +8 -24
- data/lib/formtastic/helpers/action_helper.rb +1 -48
- data/lib/formtastic/helpers/errors_helper.rb +2 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +7 -3
- data/lib/formtastic/helpers/input_helper.rb +18 -76
- data/lib/formtastic/helpers/inputs_helper.rb +12 -3
- data/lib/formtastic/i18n.rb +1 -1
- data/lib/formtastic/inputs.rb +32 -29
- data/lib/formtastic/inputs/base/collections.rb +1 -5
- data/lib/formtastic/inputs/base/errors.rb +4 -4
- data/lib/formtastic/inputs/base/hints.rb +1 -1
- data/lib/formtastic/inputs/base/timeish.rb +5 -1
- data/lib/formtastic/inputs/base/validations.rb +19 -9
- data/lib/formtastic/inputs/check_boxes_input.rb +3 -3
- data/lib/formtastic/inputs/color_input.rb +0 -1
- data/lib/formtastic/inputs/select_input.rb +1 -1
- data/lib/formtastic/localizer.rb +5 -7
- data/lib/formtastic/version.rb +1 -1
- data/lib/generators/templates/formtastic.rb +4 -6
- data/script/integration-template.rb +71 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +1 -1
- data/spec/actions/button_action_spec.rb +8 -8
- data/spec/actions/generic_action_spec.rb +60 -60
- data/spec/actions/input_action_spec.rb +7 -7
- data/spec/actions/link_action_spec.rb +10 -10
- data/spec/builder/custom_builder_spec.rb +36 -20
- data/spec/builder/error_proc_spec.rb +4 -4
- data/spec/builder/semantic_fields_for_spec.rb +27 -27
- data/spec/generators/formtastic/form/form_generator_spec.rb +25 -25
- data/spec/generators/formtastic/input/input_generator_spec.rb +31 -31
- data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
- data/spec/helpers/action_helper_spec.rb +328 -10
- data/spec/helpers/actions_helper_spec.rb +17 -17
- data/spec/helpers/form_helper_spec.rb +33 -33
- data/spec/helpers/input_helper_spec.rb +975 -2
- data/spec/helpers/inputs_helper_spec.rb +120 -105
- data/spec/helpers/reflection_helper_spec.rb +3 -3
- data/spec/helpers/semantic_errors_helper_spec.rb +22 -22
- data/spec/i18n_spec.rb +26 -26
- data/spec/input_class_finder_spec.rb +1 -1
- data/spec/inputs/base/collections_spec.rb +6 -6
- data/spec/inputs/base/validations_spec.rb +157 -19
- data/spec/inputs/boolean_input_spec.rb +55 -55
- data/spec/inputs/check_boxes_input_spec.rb +96 -95
- data/spec/inputs/color_input_spec.rb +51 -63
- data/spec/inputs/country_input_spec.rb +20 -20
- data/spec/inputs/custom_input_spec.rb +2 -6
- data/spec/inputs/datalist_input_spec.rb +1 -1
- data/spec/inputs/date_picker_input_spec.rb +42 -42
- data/spec/inputs/date_select_input_spec.rb +51 -37
- data/spec/inputs/datetime_picker_input_spec.rb +46 -46
- data/spec/inputs/datetime_select_input_spec.rb +53 -37
- data/spec/inputs/email_input_spec.rb +5 -5
- data/spec/inputs/file_input_spec.rb +6 -6
- data/spec/inputs/hidden_input_spec.rb +18 -18
- data/spec/inputs/include_blank_spec.rb +8 -8
- data/spec/inputs/label_spec.rb +20 -20
- data/spec/inputs/number_input_spec.rb +112 -112
- data/spec/inputs/password_input_spec.rb +5 -5
- data/spec/inputs/phone_input_spec.rb +5 -5
- data/spec/inputs/placeholder_spec.rb +5 -5
- data/spec/inputs/radio_input_spec.rb +63 -65
- data/spec/inputs/range_input_spec.rb +66 -66
- data/spec/inputs/readonly_spec.rb +4 -4
- data/spec/inputs/search_input_spec.rb +5 -5
- data/spec/inputs/select_input_spec.rb +92 -96
- data/spec/inputs/string_input_spec.rb +23 -23
- data/spec/inputs/text_input_spec.rb +16 -16
- data/spec/inputs/time_picker_input_spec.rb +43 -43
- data/spec/inputs/time_select_input_spec.rb +67 -54
- data/spec/inputs/time_zone_input_spec.rb +19 -19
- data/spec/inputs/url_input_spec.rb +5 -5
- data/spec/inputs/with_options_spec.rb +7 -7
- data/spec/localizer_spec.rb +17 -17
- data/spec/namespaced_class_finder_spec.rb +2 -2
- data/spec/schema.rb +21 -0
- data/spec/spec_helper.rb +163 -223
- data/spec/support/custom_macros.rb +72 -75
- data/spec/support/shared_examples.rb +0 -1301
- data/spec/support/test_environment.rb +23 -9
- metadata +33 -123
- data/Appraisals +0 -43
- data/CHANGELOG +0 -54
- data/gemfiles/rails_3.2.gemfile +0 -9
- data/gemfiles/rails_4.0.4.gemfile +0 -8
- data/gemfiles/rails_4.1.gemfile +0 -8
- data/gemfiles/rails_4.2.gemfile +0 -8
- data/gemfiles/rails_4.gemfile +0 -8
- data/gemfiles/rails_5.0.gemfile +0 -8
- data/gemfiles/rails_edge.gemfile +0 -15
- data/lib/formtastic/util.rb +0 -57
- data/spec/helpers/namespaced_action_helper_spec.rb +0 -43
- data/spec/helpers/namespaced_input_helper_spec.rb +0 -36
- data/spec/util_spec.rb +0 -66
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe 'Formtastic::Helpers::Reflection' do
|
4
|
+
RSpec.describe 'Formtastic::Helpers::Reflection' do
|
5
5
|
|
6
6
|
include FormtasticSpecHelper
|
7
7
|
|
@@ -20,11 +20,11 @@ describe 'Formtastic::Helpers::Reflection' do
|
|
20
20
|
context 'with an ActiveRecord object' do
|
21
21
|
it "should return association details on an ActiveRecord association" do
|
22
22
|
@reflection_tester = ReflectionTester.new(@new_post)
|
23
|
-
@reflection_tester.reflection_for(:sub_posts).
|
23
|
+
expect(@reflection_tester.reflection_for(:sub_posts)).not_to be_nil
|
24
24
|
end
|
25
25
|
it "should return association details on a MongoMapper association" do
|
26
26
|
@reflection_tester = ReflectionTester.new(@new_mm_post)
|
27
|
-
@reflection_tester.reflection_for(:sub_posts).
|
27
|
+
expect(@reflection_tester.reflection_for(:sub_posts)).not_to be_nil
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe 'Formtastic::FormBuilder#semantic_errors' do
|
4
|
+
RSpec.describe 'Formtastic::FormBuilder#semantic_errors' do
|
5
5
|
|
6
6
|
include FormtasticSpecHelper
|
7
7
|
|
@@ -12,31 +12,31 @@ describe 'Formtastic::FormBuilder#semantic_errors' do
|
|
12
12
|
@base_errors = ['base error message', 'nasty error']
|
13
13
|
@base_error = 'one base error'
|
14
14
|
@errors = double('errors')
|
15
|
-
@new_post.
|
15
|
+
allow(@new_post).to receive(:errors).and_return(@errors)
|
16
16
|
end
|
17
17
|
|
18
18
|
describe 'when there is only one error on base' do
|
19
19
|
before do
|
20
|
-
@errors.
|
20
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:base)).and_return(@base_error)
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should render an unordered list' do
|
24
24
|
semantic_form_for(@new_post) do |builder|
|
25
|
-
builder.semantic_errors.
|
25
|
+
expect(builder.semantic_errors).to have_tag('ul.errors li', :text => @base_error)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
describe 'when there is more than one error on base' do
|
31
31
|
before do
|
32
|
-
@errors.
|
32
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:base)).and_return(@base_errors)
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'should render an unordered list' do
|
36
36
|
semantic_form_for(@new_post) do |builder|
|
37
|
-
builder.semantic_errors.
|
37
|
+
expect(builder.semantic_errors).to have_tag('ul.errors')
|
38
38
|
@base_errors.each do |error|
|
39
|
-
builder.semantic_errors.
|
39
|
+
expect(builder.semantic_errors).to have_tag('ul.errors li', :text => error)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -44,67 +44,67 @@ describe 'Formtastic::FormBuilder#semantic_errors' do
|
|
44
44
|
|
45
45
|
describe 'when there are errors on title' do
|
46
46
|
before do
|
47
|
-
@errors.
|
48
|
-
@errors.
|
47
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:title)).and_return(@title_errors)
|
48
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:base)).and_return([])
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'should render an unordered list' do
|
52
52
|
semantic_form_for(@new_post) do |builder|
|
53
53
|
title_name = builder.send(:localized_string, :title, :title, :label) || builder.send(:humanized_attribute_name, :title)
|
54
|
-
builder.semantic_errors(:title).
|
54
|
+
expect(builder.semantic_errors(:title)).to have_tag('ul.errors li', :text => title_name << " " << @title_errors.to_sentence)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
describe 'when there are errors on title and base' do
|
60
60
|
before do
|
61
|
-
@errors.
|
62
|
-
@errors.
|
61
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:title)).and_return(@title_errors)
|
62
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:base)).and_return(@base_error)
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'should render an unordered list' do
|
66
66
|
semantic_form_for(@new_post) do |builder|
|
67
67
|
title_name = builder.send(:localized_string, :title, :title, :label) || builder.send(:humanized_attribute_name, :title)
|
68
|
-
builder.semantic_errors(:title).
|
69
|
-
builder.semantic_errors(:title).
|
68
|
+
expect(builder.semantic_errors(:title)).to have_tag('ul.errors li', :text => title_name << " " << @title_errors.to_sentence)
|
69
|
+
expect(builder.semantic_errors(:title)).to have_tag('ul.errors li', :text => @base_error)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
describe 'when there are no errors' do
|
75
75
|
before do
|
76
|
-
@errors.
|
77
|
-
@errors.
|
76
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:title)).and_return(nil)
|
77
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:base)).and_return(nil)
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'should return nil' do
|
81
81
|
semantic_form_for(@new_post) do |builder|
|
82
|
-
builder.semantic_errors(:title).
|
82
|
+
expect(builder.semantic_errors(:title)).to be_nil
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
87
|
describe 'when there is one error on base and options with class is passed' do
|
88
88
|
before do
|
89
|
-
@errors.
|
89
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:base)).and_return(@base_error)
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'should render an unordered list with given class' do
|
93
93
|
semantic_form_for(@new_post) do |builder|
|
94
|
-
builder.semantic_errors(:class => "awesome").
|
94
|
+
expect(builder.semantic_errors(:class => "awesome")).to have_tag('ul.awesome li', :text => @base_error)
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
99
|
describe 'when :base is passed in as an argument' do
|
100
100
|
before do
|
101
|
-
@errors.
|
101
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:base)).and_return(@base_error)
|
102
102
|
end
|
103
103
|
|
104
104
|
it 'should ignore :base and only render base errors once' do
|
105
105
|
semantic_form_for(@new_post) do |builder|
|
106
|
-
builder.semantic_errors(:base).
|
107
|
-
builder.semantic_errors(:base).
|
106
|
+
expect(builder.semantic_errors(:base)).to have_tag('ul li', :count => 1)
|
107
|
+
expect(builder.semantic_errors(:base)).not_to have_tag('ul li', :text => "Base #{@base_error}")
|
108
108
|
end
|
109
109
|
end
|
110
110
|
end
|
data/spec/i18n_spec.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe 'Formtastic::I18n' do
|
4
|
+
RSpec.describe 'Formtastic::I18n' do
|
5
5
|
|
6
6
|
FORMTASTIC_KEYS = [:required, :yes, :no, :create, :update].freeze
|
7
7
|
|
8
8
|
it "should be defined" do
|
9
|
-
|
9
|
+
expect { Formtastic::I18n }.not_to raise_error
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "default translations" do
|
13
13
|
it "should be defined" do
|
14
|
-
|
15
|
-
Formtastic::I18n::DEFAULT_VALUES.is_a?(::Hash).
|
14
|
+
expect { Formtastic::I18n::DEFAULT_VALUES }.not_to raise_error
|
15
|
+
expect(Formtastic::I18n::DEFAULT_VALUES.is_a?(::Hash)).to eq(true)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should exists for the core I18n lookup keys" do
|
19
|
-
(Formtastic::I18n::DEFAULT_VALUES.keys & FORMTASTIC_KEYS).size.
|
19
|
+
expect((Formtastic::I18n::DEFAULT_VALUES.keys & FORMTASTIC_KEYS).size).to eq(FORMTASTIC_KEYS.size)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -42,23 +42,23 @@ describe 'Formtastic::I18n' do
|
|
42
42
|
|
43
43
|
it "should translate core strings correctly" do
|
44
44
|
::I18n.backend.store_translations :en, {:formtastic => {:required => 'Default Required'}}
|
45
|
-
Formtastic::I18n.t(:required).
|
46
|
-
Formtastic::I18n.t(:yes).
|
47
|
-
Formtastic::I18n.t(:no).
|
48
|
-
Formtastic::I18n.t(:create, :model => 'Post').
|
49
|
-
Formtastic::I18n.t(:update, :model => 'Post').
|
45
|
+
expect(Formtastic::I18n.t(:required)).to eq("Default Required")
|
46
|
+
expect(Formtastic::I18n.t(:yes)).to eq("Default Yes")
|
47
|
+
expect(Formtastic::I18n.t(:no)).to eq("Default No")
|
48
|
+
expect(Formtastic::I18n.t(:create, :model => 'Post')).to eq("Default Create Post")
|
49
|
+
expect(Formtastic::I18n.t(:update, :model => 'Post')).to eq("Default Update Post")
|
50
50
|
end
|
51
51
|
|
52
52
|
it "should all belong to scope 'formtastic'" do
|
53
|
-
Formtastic::I18n.t(:duck, :scope => [:custom_scope]).
|
53
|
+
expect(Formtastic::I18n.t(:duck, :scope => [:custom_scope])).to eq('Duck')
|
54
54
|
end
|
55
55
|
|
56
56
|
it "should override default I18n lookup args if these are specified" do
|
57
|
-
Formtastic::I18n.t(:duck_pond, :scope => [:custom_scope], :ducks => 15).
|
57
|
+
expect(Formtastic::I18n.t(:duck_pond, :scope => [:custom_scope], :ducks => 15)).to eq('15 ducks in a pond')
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should be possible to override default values" do
|
61
|
-
Formtastic::I18n.t(:required, :default => 'Nothing found!').
|
61
|
+
expect(Formtastic::I18n.t(:required, :default => 'Nothing found!')).to eq('Nothing found!')
|
62
62
|
end
|
63
63
|
|
64
64
|
end
|
@@ -71,7 +71,7 @@ describe 'Formtastic::I18n' do
|
|
71
71
|
|
72
72
|
it "should use default strings" do
|
73
73
|
(Formtastic::I18n::DEFAULT_VALUES.keys).each do |key|
|
74
|
-
Formtastic::I18n.t(key, :model => '%{model}').
|
74
|
+
expect(Formtastic::I18n.t(key, :model => '%{model}')).to eq(Formtastic::I18n::DEFAULT_VALUES[key])
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -98,8 +98,8 @@ describe 'Formtastic::I18n' do
|
|
98
98
|
}
|
99
99
|
}}
|
100
100
|
|
101
|
-
@new_post.
|
102
|
-
@new_post.
|
101
|
+
allow(@new_post).to receive(:title)
|
102
|
+
allow(@new_post).to receive(:column_for_attribute).with(:title).and_return(double('column', :type => :string, :limit => 255))
|
103
103
|
end
|
104
104
|
|
105
105
|
after do
|
@@ -108,7 +108,7 @@ describe 'Formtastic::I18n' do
|
|
108
108
|
|
109
109
|
it "lookup scopes should be defined" do
|
110
110
|
with_config :i18n_lookups_by_default, true do
|
111
|
-
|
111
|
+
expect { Formtastic::I18n::SCOPES }.not_to raise_error
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -117,7 +117,7 @@ describe 'Formtastic::I18n' do
|
|
117
117
|
concat(semantic_form_for(@new_post) do |builder|
|
118
118
|
concat(builder.input(:title))
|
119
119
|
end)
|
120
|
-
output_buffer.
|
120
|
+
expect(output_buffer).to have_tag("form label", :text => /Hello post!/)
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
@@ -126,7 +126,7 @@ describe 'Formtastic::I18n' do
|
|
126
126
|
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
127
127
|
concat(builder.input(:title))
|
128
128
|
end)
|
129
|
-
output_buffer.
|
129
|
+
expect(output_buffer).to have_tag("form label", :text => /Hello project!/)
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -135,7 +135,7 @@ describe 'Formtastic::I18n' do
|
|
135
135
|
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
136
136
|
concat(builder.input(:author))
|
137
137
|
end)
|
138
|
-
output_buffer.
|
138
|
+
expect(output_buffer).to have_tag("form label", :text => /Author/)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
@@ -146,7 +146,7 @@ describe 'Formtastic::I18n' do
|
|
146
146
|
concat(f.input(:name))
|
147
147
|
end)
|
148
148
|
end)
|
149
|
-
output_buffer.
|
149
|
+
expect(output_buffer).to have_tag("form label", :text => /Hello author name!/)
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
@@ -157,7 +157,7 @@ describe 'Formtastic::I18n' do
|
|
157
157
|
concat(f.input(:name))
|
158
158
|
end
|
159
159
|
end)
|
160
|
-
output_buffer.
|
160
|
+
expect(output_buffer).to have_tag("form label", :text => /Hello author name!/)
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
@@ -168,7 +168,7 @@ describe 'Formtastic::I18n' do
|
|
168
168
|
concat(f.input(:title))
|
169
169
|
end
|
170
170
|
end)
|
171
|
-
output_buffer.
|
171
|
+
expect(output_buffer).to have_tag("form label", :text => /Hello project!/)
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
@@ -179,7 +179,7 @@ describe 'Formtastic::I18n' do
|
|
179
179
|
concat(f.input(:name))
|
180
180
|
end
|
181
181
|
end)
|
182
|
-
output_buffer.
|
182
|
+
expect(output_buffer).to have_tag("form label", :text => /Hello author name!/)
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
@@ -188,7 +188,7 @@ describe 'Formtastic::I18n' do
|
|
188
188
|
concat(semantic_form_for(@new_post) do |builder|
|
189
189
|
concat(builder.input(:body))
|
190
190
|
end)
|
191
|
-
output_buffer.
|
191
|
+
expect(output_buffer).to have_tag("form label", :text => /Elaborate/)
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
@@ -199,7 +199,7 @@ describe 'Formtastic::I18n' do
|
|
199
199
|
concat(f.input(:login))
|
200
200
|
end)
|
201
201
|
end)
|
202
|
-
output_buffer.
|
202
|
+
expect(output_buffer).to have_tag("form label", :text => /Hello login/)
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
require 'formtastic/input_class_finder'
|
4
4
|
|
5
|
-
describe Formtastic::InputClassFinder do
|
5
|
+
RSpec.describe Formtastic::InputClassFinder do
|
6
6
|
it_behaves_like 'Specialized Class Finder' do
|
7
7
|
let(:default) { Formtastic::Inputs }
|
8
8
|
let(:namespaces_setting) { :input_namespaces }
|
@@ -5,7 +5,7 @@ class MyInput
|
|
5
5
|
include Formtastic::Inputs::Base::Collections
|
6
6
|
end
|
7
7
|
|
8
|
-
describe MyInput do
|
8
|
+
RSpec.describe MyInput do
|
9
9
|
let(:builder) { double }
|
10
10
|
let(:template) { double }
|
11
11
|
let(:model_class) { double }
|
@@ -32,13 +32,13 @@ describe MyInput do
|
|
32
32
|
context "when an enum is defined for the method" do
|
33
33
|
before do
|
34
34
|
statuses = ActiveSupport::HashWithIndifferentAccess.new("active"=>0, "inactive"=>1)
|
35
|
-
model_class.
|
36
|
-
model.
|
35
|
+
allow(model_class).to receive(:statuses) { statuses }
|
36
|
+
allow(model).to receive(:defined_enums) { {"status" => statuses } }
|
37
37
|
end
|
38
38
|
|
39
39
|
context 'no translations available' do
|
40
40
|
it 'returns an Array of EnumOption objects based on the enum options hash' do
|
41
|
-
instance.collection_from_enum.
|
41
|
+
expect(instance.collection_from_enum).to eq [["Active", "active"],["Inactive", "inactive"]]
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -56,7 +56,7 @@ describe MyInput do
|
|
56
56
|
}
|
57
57
|
end
|
58
58
|
it 'returns an Array of EnumOption objects based on the enum options hash' do
|
59
|
-
instance.collection_from_enum.
|
59
|
+
expect(instance.collection_from_enum).to eq [["I am active", "active"],["I am inactive", "inactive"]]
|
60
60
|
end
|
61
61
|
|
62
62
|
after do
|
@@ -67,7 +67,7 @@ describe MyInput do
|
|
67
67
|
|
68
68
|
context "when an enum is not defined" do
|
69
69
|
it 'returns nil' do
|
70
|
-
instance.collection_from_enum.
|
70
|
+
expect(instance.collection_from_enum).to eq nil
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
@@ -1,11 +1,17 @@
|
|
1
1
|
require 'fast_spec_helper'
|
2
|
+
require 'active_model'
|
2
3
|
require 'inputs/base/validations'
|
3
4
|
|
4
5
|
class MyInput
|
6
|
+
attr_accessor :validations
|
5
7
|
include Formtastic::Inputs::Base::Validations
|
8
|
+
|
9
|
+
def validations?
|
10
|
+
true
|
11
|
+
end
|
6
12
|
end
|
7
13
|
|
8
|
-
describe MyInput do
|
14
|
+
RSpec.describe MyInput do
|
9
15
|
let(:builder) { double }
|
10
16
|
let(:template) { double }
|
11
17
|
let(:model_class) { double }
|
@@ -14,14 +20,15 @@ describe MyInput do
|
|
14
20
|
let(:method) { double }
|
15
21
|
let(:options) { Hash.new }
|
16
22
|
let(:validator) { double }
|
17
|
-
let(:instance)
|
23
|
+
let(:instance) do
|
24
|
+
MyInput.new(builder, template, model, model_name, method, options).tap do |my_input|
|
25
|
+
my_input.validations = validations
|
26
|
+
end
|
27
|
+
end
|
18
28
|
|
19
29
|
describe '#required?' do
|
20
30
|
context 'with a single validator' do
|
21
|
-
|
22
|
-
allow(instance).to receive(:validations?).and_return(:true)
|
23
|
-
allow(instance).to receive(:validations).and_return([validator])
|
24
|
-
end
|
31
|
+
let(:validations) { [validator] }
|
25
32
|
|
26
33
|
context 'with options[:required] being true' do
|
27
34
|
let(:options) { {required: true} }
|
@@ -292,14 +299,14 @@ describe MyInput do
|
|
292
299
|
end
|
293
300
|
|
294
301
|
context 'with multiple validators' do
|
302
|
+
let(:validations) { [validator1, validator2] }
|
303
|
+
|
295
304
|
context 'with a on create presence validator and a on update presence validator' do
|
296
|
-
let
|
297
|
-
let
|
305
|
+
let(:validator1) { double(options: {on: :create}, kind: :presence) }
|
306
|
+
let(:validator2) { double(options: {}, kind: :presence) }
|
298
307
|
|
299
|
-
before :
|
308
|
+
before :example do
|
300
309
|
allow(model).to receive(:new_record?).and_return(false)
|
301
|
-
allow(instance).to receive(:validations?).and_return(:true)
|
302
|
-
allow(instance).to receive(:validations).and_return([validator1, validator2])
|
303
310
|
end
|
304
311
|
|
305
312
|
it 'is required' do
|
@@ -311,10 +318,8 @@ describe MyInput do
|
|
311
318
|
let (:validator1) { double(options: {on: :create}, kind: :presence) }
|
312
319
|
let (:validator2) { double(options: {}, kind: :presence) }
|
313
320
|
|
314
|
-
before :
|
321
|
+
before :example do
|
315
322
|
allow(model).to receive(:new_record?).and_return(false)
|
316
|
-
allow(instance).to receive(:validations?).and_return(:true)
|
317
|
-
allow(instance).to receive(:validations).and_return([validator1, validator2])
|
318
323
|
end
|
319
324
|
|
320
325
|
it 'is required' do
|
@@ -323,13 +328,11 @@ describe MyInput do
|
|
323
328
|
end
|
324
329
|
|
325
330
|
context 'with a on create presence validator and a allow blank inclusion validator' do
|
326
|
-
let
|
327
|
-
let
|
331
|
+
let(:validator1) { double(options: {on: :create}, kind: :presence) }
|
332
|
+
let(:validator2) { double(options: {allow_blank: true}, kind: :inclusion) }
|
328
333
|
|
329
|
-
before :
|
334
|
+
before :example do
|
330
335
|
allow(model).to receive(:new_record?).and_return(false)
|
331
|
-
allow(instance).to receive(:validations?).and_return(:true)
|
332
|
-
allow(instance).to receive(:validations).and_return([validator1, validator2])
|
333
336
|
end
|
334
337
|
|
335
338
|
it 'is required' do
|
@@ -338,5 +341,140 @@ describe MyInput do
|
|
338
341
|
end
|
339
342
|
end
|
340
343
|
end
|
344
|
+
|
345
|
+
describe '#validation_min' do
|
346
|
+
let(:validations) { [validator] }
|
347
|
+
|
348
|
+
context 'with a greater_than numericality validator' do
|
349
|
+
let(:validator) { double(options: { greater_than: option_value }, kind: :numericality) }
|
350
|
+
|
351
|
+
context 'with a symbol' do
|
352
|
+
let(:option_value) { :a_symbol }
|
353
|
+
|
354
|
+
it 'returns one greater' do
|
355
|
+
allow(model).to receive(:send).with(option_value).and_return(14)
|
356
|
+
expect(instance.validation_min).to eq 15
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'with a proc' do
|
361
|
+
let(:option_value) { Proc.new { 10 } }
|
362
|
+
|
363
|
+
it 'returns one greater' do
|
364
|
+
expect(instance.validation_min).to eq 11
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
context 'with a number' do
|
369
|
+
let(:option_value) { 8 }
|
370
|
+
|
371
|
+
it 'returns one greater' do
|
372
|
+
expect(instance.validation_min).to eq 9
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
context 'with a greater_than_or_equal_to numericality validator' do
|
378
|
+
let(:validator) do
|
379
|
+
double(
|
380
|
+
options: { greater_than_or_equal_to: option_value },
|
381
|
+
kind: :numericality
|
382
|
+
)
|
383
|
+
end
|
384
|
+
|
385
|
+
context 'with a symbol' do
|
386
|
+
let(:option_value) { :a_symbol }
|
387
|
+
|
388
|
+
it 'returns the instance method amount' do
|
389
|
+
allow(model).to receive(:send).with(option_value).and_return(14)
|
390
|
+
expect(instance.validation_min).to eq 14
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'with a proc' do
|
395
|
+
let(:option_value) { Proc.new { 10 } }
|
396
|
+
|
397
|
+
it 'returns the proc amount' do
|
398
|
+
expect(instance.validation_min).to eq 10
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
context 'with a number' do
|
403
|
+
let(:option_value) { 8 }
|
404
|
+
|
405
|
+
it 'returns the number' do
|
406
|
+
expect(instance.validation_min).to eq 8
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
describe '#validation_max' do
|
413
|
+
let(:validations) do
|
414
|
+
[
|
415
|
+
ActiveModel::Validations::NumericalityValidator.new(
|
416
|
+
validator_options.merge(attributes: :an_attribute)
|
417
|
+
)
|
418
|
+
]
|
419
|
+
end
|
420
|
+
|
421
|
+
context 'with a less_than numericality validator' do
|
422
|
+
let(:validator_options) { { less_than: option_value } }
|
423
|
+
|
424
|
+
context 'with a symbol' do
|
425
|
+
let(:option_value) { :a_symbol }
|
426
|
+
|
427
|
+
it 'returns one less' do
|
428
|
+
allow(model).to receive(:send).with(option_value).and_return(14)
|
429
|
+
expect(instance.validation_max).to eq 13
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
context 'with a proc' do
|
434
|
+
let(:option_value) { proc { 10 } }
|
435
|
+
|
436
|
+
it 'returns one less' do
|
437
|
+
expect(instance.validation_max).to eq 9
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
context 'with a number' do
|
442
|
+
let(:option_value) { 8 }
|
443
|
+
|
444
|
+
it 'returns one less' do
|
445
|
+
expect(instance.validation_max).to eq 7
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
context 'with a less_than_or_equal_to numericality validator' do
|
451
|
+
let(:validator_options) { { less_than_or_equal_to: option_value } }
|
452
|
+
|
453
|
+
context 'with a symbol' do
|
454
|
+
let(:option_value) { :a_symbol }
|
455
|
+
|
456
|
+
it 'returns the instance method amount' do
|
457
|
+
allow(model).to receive(:send).with(option_value).and_return(14)
|
458
|
+
expect(instance.validation_max).to eq 14
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
context 'with a proc' do
|
463
|
+
let(:option_value) { proc { 10 } }
|
464
|
+
|
465
|
+
it 'returns the proc amount' do
|
466
|
+
expect(instance.validation_max).to eq 10
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
context 'with a number' do
|
471
|
+
let(:option_value) { 8 }
|
472
|
+
|
473
|
+
it 'returns the number' do
|
474
|
+
expect(instance.validation_max).to eq 8
|
475
|
+
end
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
341
479
|
end
|
342
480
|
|