careacademy-enumerize 2.8.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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +69 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +327 -0
- data/Gemfile +6 -0
- data/Gemfile.global +12 -0
- data/Gemfile.mongo_mapper +6 -0
- data/Gemfile.rails60 +6 -0
- data/Gemfile.rails61 +6 -0
- data/Gemfile.rails70 +9 -0
- data/Gemfile.railsmaster +5 -0
- data/MIT-LICENSE +22 -0
- data/README.md +641 -0
- data/Rakefile +17 -0
- data/enumerize.gemspec +22 -0
- data/lib/enumerize/activemodel.rb +47 -0
- data/lib/enumerize/activerecord.rb +142 -0
- data/lib/enumerize/attribute.rb +192 -0
- data/lib/enumerize/attribute_map.rb +40 -0
- data/lib/enumerize/base.rb +112 -0
- data/lib/enumerize/hooks/formtastic.rb +27 -0
- data/lib/enumerize/hooks/sequel_dataset.rb +17 -0
- data/lib/enumerize/hooks/simple_form.rb +37 -0
- data/lib/enumerize/hooks/uniqueness.rb +22 -0
- data/lib/enumerize/integrations/rails_admin.rb +18 -0
- data/lib/enumerize/integrations/rspec/matcher.rb +164 -0
- data/lib/enumerize/integrations/rspec.rb +19 -0
- data/lib/enumerize/module.rb +33 -0
- data/lib/enumerize/module_attributes.rb +12 -0
- data/lib/enumerize/mongoid.rb +29 -0
- data/lib/enumerize/predicatable.rb +23 -0
- data/lib/enumerize/predicates.rb +76 -0
- data/lib/enumerize/scope/activerecord.rb +53 -0
- data/lib/enumerize/scope/mongoid.rb +50 -0
- data/lib/enumerize/scope/sequel.rb +56 -0
- data/lib/enumerize/sequel.rb +62 -0
- data/lib/enumerize/set.rb +81 -0
- data/lib/enumerize/utils.rb +12 -0
- data/lib/enumerize/value.rb +47 -0
- data/lib/enumerize/version.rb +5 -0
- data/lib/enumerize.rb +90 -0
- data/lib/sequel/plugins/enumerize.rb +18 -0
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +261 -0
- data/spec/spec_helper.rb +30 -0
- data/test/activemodel_test.rb +114 -0
- data/test/activerecord_test.rb +679 -0
- data/test/attribute_map_test.rb +70 -0
- data/test/attribute_test.rb +141 -0
- data/test/base_test.rb +230 -0
- data/test/formtastic_test.rb +152 -0
- data/test/module_attributes_test.rb +52 -0
- data/test/mongo_mapper_test.rb +83 -0
- data/test/mongoid_test.rb +164 -0
- data/test/multiple_test.rb +65 -0
- data/test/predicates_test.rb +65 -0
- data/test/rails_admin_test.rb +27 -0
- data/test/sequel_test.rb +344 -0
- data/test/set_test.rb +166 -0
- data/test/simple_form_test.rb +156 -0
- data/test/support/mock_controller.rb +31 -0
- data/test/support/shared_enums.rb +43 -0
- data/test/support/view_test_helper.rb +46 -0
- data/test/test_helper.rb +53 -0
- data/test/value_test.rb +158 -0
- metadata +143 -0
data/test/sequel_test.rb
ADDED
@@ -0,0 +1,344 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'sequel'
|
5
|
+
require 'logger'
|
6
|
+
require 'jdbc/sqlite3' if RUBY_PLATFORM == 'java'
|
7
|
+
|
8
|
+
module SequelTest
|
9
|
+
silence_warnings do
|
10
|
+
DB = if RUBY_PLATFORM == 'java'
|
11
|
+
Sequel.connect('jdbc:sqlite::memory:')
|
12
|
+
else
|
13
|
+
Sequel.sqlite
|
14
|
+
end
|
15
|
+
DB.loggers << Logger.new(nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
DB.create_table :users do
|
19
|
+
primary_key :id
|
20
|
+
String :sex
|
21
|
+
String :role
|
22
|
+
String :lambda_role
|
23
|
+
String :name
|
24
|
+
String :interests
|
25
|
+
String :status
|
26
|
+
Integer :skill
|
27
|
+
String :account_type, default: "basic"
|
28
|
+
String :foo
|
29
|
+
end
|
30
|
+
|
31
|
+
DB.create_table :documents do
|
32
|
+
primary_key :id
|
33
|
+
String :visibility
|
34
|
+
Time :created_at
|
35
|
+
Time :updated_at
|
36
|
+
end
|
37
|
+
|
38
|
+
class Document < Sequel::Model
|
39
|
+
plugin :enumerize
|
40
|
+
enumerize :visibility, :in => [:public, :private, :protected], :scope => true, :default => :public
|
41
|
+
end
|
42
|
+
|
43
|
+
module RoleEnum
|
44
|
+
extend Enumerize
|
45
|
+
enumerize :role, :in => [:user, :admin], :default => :user, scope: :having_role
|
46
|
+
enumerize :lambda_role, :in => [:user, :admin], :default => lambda { :admin }
|
47
|
+
end
|
48
|
+
|
49
|
+
class User < Sequel::Model
|
50
|
+
plugin :serialization, :json, :interests
|
51
|
+
plugin :dirty
|
52
|
+
plugin :defaults_setter
|
53
|
+
plugin :validation_helpers
|
54
|
+
plugin :enumerize
|
55
|
+
include RoleEnum
|
56
|
+
|
57
|
+
enumerize :sex, :in => [:male, :female], scope: :shallow
|
58
|
+
|
59
|
+
enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true
|
60
|
+
|
61
|
+
enumerize :status, :in => { active: 1, blocked: 2 }, scope: true
|
62
|
+
|
63
|
+
enumerize :skill, :in => { noob: 0, casual: 1, pro: 2 }, scope: :shallow
|
64
|
+
|
65
|
+
enumerize :account_type, :in => [:basic, :premium]
|
66
|
+
end
|
67
|
+
|
68
|
+
class UniqStatusUser < User
|
69
|
+
def validate
|
70
|
+
super
|
71
|
+
validates_unique :status
|
72
|
+
validates_presence :sex
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class SkipValidationsUser < Sequel::Model(:users)
|
77
|
+
include SkipValidationsEnum
|
78
|
+
end
|
79
|
+
|
80
|
+
class DoNotSkipValidationsUser < Sequel::Model(:users)
|
81
|
+
include DoNotSkipValidationsEnum
|
82
|
+
end
|
83
|
+
|
84
|
+
class SkipValidationsLambdaUser < Sequel::Model(:users)
|
85
|
+
include SkipValidationsLambdaEnum
|
86
|
+
end
|
87
|
+
|
88
|
+
class SkipValidationsLambdaWithParamUser < Sequel::Model(:users)
|
89
|
+
include SkipValidationsLambdaWithParamEnum
|
90
|
+
end
|
91
|
+
|
92
|
+
describe Enumerize::SequelSupport do
|
93
|
+
it 'sets nil if invalid value is passed' do
|
94
|
+
user = User.new
|
95
|
+
user.sex = :invalid
|
96
|
+
expect(user.sex).must_be_nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'saves value' do
|
100
|
+
User.filter{ true }.delete
|
101
|
+
user = User.new
|
102
|
+
user.sex = :female
|
103
|
+
user.save
|
104
|
+
expect(user.sex).must_equal 'female'
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'loads value' do
|
108
|
+
User.filter{ true }.delete
|
109
|
+
User.create(:sex => :male)
|
110
|
+
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
|
111
|
+
user = User.first
|
112
|
+
expect(user.sex).must_equal 'male'
|
113
|
+
expect(user.sex_text).must_equal 'Male'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'has default value' do
|
118
|
+
expect(User.new.role).must_equal 'user'
|
119
|
+
expect(User.new.values[:role]).must_equal 'user'
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'does not set default value for not selected attributes' do
|
123
|
+
User.filter{ true }.delete
|
124
|
+
User.create(:sex => :male)
|
125
|
+
|
126
|
+
assert_equal [:id], User.select(:id).first.values.keys
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'has default value with lambda' do
|
130
|
+
expect(User.new.lambda_role).must_equal 'admin'
|
131
|
+
expect(User.new.values[:lambda_role]).must_equal 'admin'
|
132
|
+
end
|
133
|
+
it 'uses after_initialize callback to set default value' do
|
134
|
+
User.filter{ true }.delete
|
135
|
+
User.create(sex: 'male', lambda_role: nil)
|
136
|
+
|
137
|
+
user = User.where(:sex => 'male').first
|
138
|
+
expect(user.lambda_role).must_equal 'admin'
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'uses default value from db column' do
|
142
|
+
expect(User.new.account_type).must_equal 'basic'
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'validates inclusion' do
|
146
|
+
user = User.new
|
147
|
+
user.role = 'wrong'
|
148
|
+
expect(user).wont_be :valid?
|
149
|
+
expect(user.errors[:role]).must_include 'is not included in the list'
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'validates inclusion on mass assignment' do
|
153
|
+
assert_raises Sequel::ValidationFailed do
|
154
|
+
User.create(role: 'wrong')
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "uses persisted value for validation if it hasn't been set" do
|
159
|
+
user = User.create :sex => :male
|
160
|
+
expect(User[user.id].read_attribute_for_validation(:sex)).must_equal 'male'
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'is valid with empty string assigned' do
|
164
|
+
user = User.new
|
165
|
+
user.role = ''
|
166
|
+
expect(user).must_be :valid?
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'stores nil when empty string assigned' do
|
170
|
+
user = User.new
|
171
|
+
user.role = ''
|
172
|
+
expect(user.values[:role]).must_be_nil
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'validates inclusion when :skip_validations = false' do
|
176
|
+
user = DoNotSkipValidationsUser.new
|
177
|
+
user.foo = 'wrong'
|
178
|
+
expect(user).wont_be :valid?
|
179
|
+
expect(user.errors[:foo]).must_include 'is not included in the list'
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'does not validate inclusion when :skip_validations = true' do
|
183
|
+
user = SkipValidationsUser.new
|
184
|
+
user.foo = 'wrong'
|
185
|
+
expect(user).must_be :valid?
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'supports :skip_validations option as lambda' do
|
189
|
+
user = SkipValidationsLambdaUser.new
|
190
|
+
user.foo = 'wrong'
|
191
|
+
expect(user).must_be :valid?
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'supports :skip_validations option as lambda with a parameter' do
|
195
|
+
user = SkipValidationsLambdaWithParamUser.new
|
196
|
+
user.foo = 'wrong'
|
197
|
+
expect(user).must_be :valid?
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'supports multiple attributes' do
|
201
|
+
user = User.new
|
202
|
+
user.interests ||= []
|
203
|
+
expect(user.interests).must_be_empty
|
204
|
+
user.interests << "music"
|
205
|
+
expect(user.interests).must_equal %w(music)
|
206
|
+
user.save
|
207
|
+
|
208
|
+
user = User[user.id]
|
209
|
+
expect(user.interests).must_be_instance_of Enumerize::Set
|
210
|
+
expect(user.interests).must_equal %w(music)
|
211
|
+
user.interests << "sports"
|
212
|
+
expect(user.interests).must_equal %w(music sports)
|
213
|
+
|
214
|
+
user.interests = []
|
215
|
+
interests = user.interests
|
216
|
+
interests << "music"
|
217
|
+
expect(interests).must_equal %w(music)
|
218
|
+
interests << "dancing"
|
219
|
+
expect(interests).must_equal %w(music dancing)
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'returns invalid multiple value for validation' do
|
223
|
+
user = User.new
|
224
|
+
user.interests << :music
|
225
|
+
user.interests << :invalid
|
226
|
+
values = user.read_attribute_for_validation(:interests)
|
227
|
+
expect(values).must_equal %w(music invalid)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'validates multiple attributes' do
|
231
|
+
user = User.new
|
232
|
+
user.interests << :invalid
|
233
|
+
expect(user).wont_be :valid?
|
234
|
+
|
235
|
+
user.interests = Object.new
|
236
|
+
expect(user).wont_be :valid?
|
237
|
+
|
238
|
+
user.interests = ['music', '']
|
239
|
+
expect(user).must_be :valid?
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'stores custom values for multiple attributes' do
|
243
|
+
User.filter{ true }.delete
|
244
|
+
|
245
|
+
klass = Class.new(User)
|
246
|
+
klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
|
247
|
+
|
248
|
+
user = klass.new
|
249
|
+
user.interests << :music
|
250
|
+
expect(user.interests).must_equal %w(music)
|
251
|
+
user.save
|
252
|
+
|
253
|
+
user = klass[user.id]
|
254
|
+
expect(user.interests).must_equal %w(music)
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'adds scope' do
|
258
|
+
User.filter{ true }.delete
|
259
|
+
|
260
|
+
user_1 = User.create(sex: :female, skill: :noob, status: :active, role: :admin)
|
261
|
+
user_2 = User.create(sex: :female, skill: :casual, status: :blocked)
|
262
|
+
user_3 = User.create(sex: :male, skill: :pro)
|
263
|
+
|
264
|
+
expect(User.with_status(:active).to_a).must_equal [user_1]
|
265
|
+
expect(User.with_status(:blocked).to_a).must_equal [user_2]
|
266
|
+
expect(User.with_status(:active, :blocked).to_set).must_equal [user_1, user_2].to_set
|
267
|
+
|
268
|
+
expect(User.without_status(:active).to_a).must_equal [user_2]
|
269
|
+
expect(User.without_status(:active, :blocked).to_a).must_equal []
|
270
|
+
|
271
|
+
expect(User.having_role(:admin).to_a).must_equal [user_1]
|
272
|
+
expect(User.male.to_a).must_equal [user_3]
|
273
|
+
expect(User.pro.to_a).must_equal [user_3]
|
274
|
+
|
275
|
+
expect(User.not_male.to_set).must_equal [user_1, user_2].to_set
|
276
|
+
expect(User.not_pro.to_set).must_equal [user_1, user_2].to_set
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'allows either key or value as valid' do
|
280
|
+
user_1 = User.new(status: :active)
|
281
|
+
user_2 = User.new(status: 1)
|
282
|
+
user_3 = User.new(status: '1')
|
283
|
+
|
284
|
+
expect(user_1.status).must_equal 'active'
|
285
|
+
expect(user_2.status).must_equal 'active'
|
286
|
+
expect(user_3.status).must_equal 'active'
|
287
|
+
|
288
|
+
expect(user_1).must_be :valid?
|
289
|
+
expect(user_2).must_be :valid?
|
290
|
+
expect(user_3).must_be :valid?
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'supports defining enumerized attributes on abstract class' do
|
294
|
+
Document.filter{ true }.delete
|
295
|
+
|
296
|
+
document = Document.new
|
297
|
+
document.visibility = :protected
|
298
|
+
expect(document.visibility).must_equal 'protected'
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'supports defining enumerized scopes on abstract class' do
|
302
|
+
Document.filter{ true }.delete
|
303
|
+
|
304
|
+
document_1 = Document.create(visibility: :public)
|
305
|
+
document_2 = Document.create(visibility: :private)
|
306
|
+
|
307
|
+
expect(Document.with_visibility(:public).to_a).must_equal [document_1]
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'validates uniqueness' do
|
311
|
+
user = User.create(status: :active, sex: "male")
|
312
|
+
|
313
|
+
user = UniqStatusUser.new
|
314
|
+
user.sex = "male"
|
315
|
+
user.status = :active
|
316
|
+
expect(user.valid?).must_equal false
|
317
|
+
|
318
|
+
expect(user.errors[:status]).wont_be :empty?
|
319
|
+
end
|
320
|
+
|
321
|
+
it "doesn't update record" do
|
322
|
+
Document.filter{ true }.delete
|
323
|
+
|
324
|
+
expected = Time.new(2010, 10, 10)
|
325
|
+
|
326
|
+
document = Document.new
|
327
|
+
document.updated_at = expected
|
328
|
+
document.save
|
329
|
+
|
330
|
+
document = Document.last
|
331
|
+
document.save
|
332
|
+
|
333
|
+
assert_equal expected, document.updated_at
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'changes from dirty should be serialized as scalar values' do
|
337
|
+
user = User.create(:status => :active)
|
338
|
+
user.status = :blocked
|
339
|
+
|
340
|
+
expected = { status: [1, 2] }.to_yaml
|
341
|
+
assert_equal expected, user.column_changes.to_yaml
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
data/test/set_test.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
describe Enumerize::Set do
|
7
|
+
let(:kklass) do
|
8
|
+
Class.new do
|
9
|
+
extend Enumerize
|
10
|
+
enumerize :foo, :in => %w(a b c), :multiple => true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:object) { kklass.new }
|
15
|
+
|
16
|
+
def build_set(values)
|
17
|
+
@set = Enumerize::Set.new(object, kklass.foo, values)
|
18
|
+
end
|
19
|
+
|
20
|
+
def set
|
21
|
+
@set
|
22
|
+
end
|
23
|
+
|
24
|
+
def assert_called(object, method)
|
25
|
+
called = false
|
26
|
+
|
27
|
+
object.singleton_class.class_eval do
|
28
|
+
define_method method do |*args, &block|
|
29
|
+
called = true
|
30
|
+
super(*args, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
yield
|
35
|
+
|
36
|
+
assert called, "Expected ##{method} to be called"
|
37
|
+
end
|
38
|
+
|
39
|
+
before do
|
40
|
+
build_set %w(a)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'equals to other set' do
|
44
|
+
expect(set).must_equal Enumerize::Set.new(nil, kklass.foo, %w(a))
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'equals to array' do
|
48
|
+
expect(set).must_equal %w(a)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'equals to array of symbols' do
|
52
|
+
expect(set).must_equal [:a]
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'has unique values' do
|
56
|
+
set << :a
|
57
|
+
expect(set).must_equal %w(a)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'equals to array with different value order' do
|
61
|
+
set << :b
|
62
|
+
expect(set).must_equal %w(b a)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "isn't equal to a part of values" do
|
66
|
+
set << :b
|
67
|
+
expect(set).wont_equal %w(a)
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#push' do
|
71
|
+
it 'appends values' do
|
72
|
+
set.push :b
|
73
|
+
expect(set).must_include :b
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'reassigns attribute' do
|
77
|
+
assert_called object, :foo= do
|
78
|
+
set.push :b
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#delete' do
|
84
|
+
it 'deletes value' do
|
85
|
+
set.delete :a
|
86
|
+
expect(set).wont_include :a
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'reassigns attribute' do
|
90
|
+
assert_called object, :foo= do
|
91
|
+
set.delete :a
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#inspect' do
|
97
|
+
it 'returns custom string' do
|
98
|
+
set << :b
|
99
|
+
expect(set.inspect).must_equal '#<Enumerize::Set {a, b}>'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#to_ary' do
|
104
|
+
it 'returns array' do
|
105
|
+
expect(set.to_ary).must_be_instance_of Array
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#texts' do
|
110
|
+
it 'returns array of text values' do
|
111
|
+
expect(set.texts).must_equal ['A']
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#join' do
|
116
|
+
it 'joins values' do
|
117
|
+
set << :b
|
118
|
+
expect(set.join(', ')).must_equal 'a, b'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe 'boolean methods comparison' do
|
123
|
+
it 'returns true if value equals method' do
|
124
|
+
set << :a
|
125
|
+
expect(set.a?).must_equal true
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'returns false if value does not equal method' do
|
129
|
+
set << :a
|
130
|
+
expect(set.b?).must_equal false
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'raises NoMethodError if there are no values like boolean method' do
|
134
|
+
expect(proc {
|
135
|
+
set.some_method?
|
136
|
+
}).must_raise NoMethodError
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'raises ArgumentError if arguments are passed' do
|
140
|
+
expect(proc {
|
141
|
+
set.a?('<3')
|
142
|
+
}).must_raise ArgumentError
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'responds to methods for existing values' do
|
146
|
+
expect(set).must_respond_to :a?
|
147
|
+
expect(set).must_respond_to :b?
|
148
|
+
expect(set).must_respond_to :c?
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'returns a method object' do
|
152
|
+
expect(set.method(:a?)).must_be_instance_of Method
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'does not respond to a method for not existing value' do
|
156
|
+
expect(set).wont_respond_to :some_method?
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe 'serialization' do
|
161
|
+
it 'is serialized to yaml as array' do
|
162
|
+
set << :a
|
163
|
+
assert_equal YAML.dump(%w(a)), YAML.dump(set)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'simple_form/version'
|
5
|
+
|
6
|
+
class SimpleFormSpec < MiniTest::Spec
|
7
|
+
include ViewTestHelper
|
8
|
+
include SimpleForm::ActionViewExtensions::FormHelper
|
9
|
+
|
10
|
+
class Thing < Struct.new(:name)
|
11
|
+
extend ActiveModel::Naming
|
12
|
+
include ActiveModel::Conversion
|
13
|
+
|
14
|
+
def persisted?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class User < Struct.new(:sex, :age)
|
20
|
+
extend ActiveModel::Naming
|
21
|
+
include ActiveModel::Conversion
|
22
|
+
|
23
|
+
extend Enumerize
|
24
|
+
|
25
|
+
enumerize :sex, :in => [:male, :female]
|
26
|
+
|
27
|
+
def persisted?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Post < Struct.new(:category, :title)
|
33
|
+
extend ActiveModel::Naming
|
34
|
+
include ActiveModel::Conversion
|
35
|
+
|
36
|
+
extend Enumerize
|
37
|
+
|
38
|
+
enumerize :categories, :in => [:music, :games], :multiple => true
|
39
|
+
|
40
|
+
def persisted?
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Registration < Struct.new(:sex)
|
46
|
+
extend Enumerize
|
47
|
+
|
48
|
+
enumerize :sex, in: [:male, :female]
|
49
|
+
end
|
50
|
+
|
51
|
+
let(:user) { User.new }
|
52
|
+
let(:post) { Post.new }
|
53
|
+
|
54
|
+
it 'renders select with enumerized values using input_field' do
|
55
|
+
concat(simple_form_for(user) do |f|
|
56
|
+
f.input_field(:sex)
|
57
|
+
end)
|
58
|
+
|
59
|
+
assert_select 'select option[value=male]'
|
60
|
+
assert_select 'select option[value=female]'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'renders select with enumerized values' do
|
64
|
+
concat(simple_form_for(user) do |f|
|
65
|
+
f.input(:sex)
|
66
|
+
end)
|
67
|
+
|
68
|
+
assert_select 'select option[value=male]'
|
69
|
+
assert_select 'select option[value=female]'
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'renders multiple select with enumerized values' do
|
73
|
+
concat(simple_form_for(post) do |f|
|
74
|
+
f.input(:categories)
|
75
|
+
end)
|
76
|
+
|
77
|
+
assert_select 'select[multiple=multiple]'
|
78
|
+
assert_select 'select option[value=music]'
|
79
|
+
assert_select 'select option[value=games]'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'renders multiple select with selected enumerized value' do
|
83
|
+
post.categories << :music
|
84
|
+
|
85
|
+
concat(simple_form_for(post) do |f|
|
86
|
+
f.input(:categories)
|
87
|
+
end)
|
88
|
+
|
89
|
+
assert_select 'select[multiple=multiple]'
|
90
|
+
assert_select 'select option[value=music][selected=selected]'
|
91
|
+
assert_select 'select option[value=games][selected=selected]', count: 0
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'renders checkboxes with enumerized values' do
|
95
|
+
concat(simple_form_for(post) do |f|
|
96
|
+
f.input(:categories, as: :check_boxes)
|
97
|
+
end)
|
98
|
+
|
99
|
+
assert_select 'select[multiple=multiple]', count: 0
|
100
|
+
assert_select 'input[type=checkbox][value=music]'
|
101
|
+
assert_select 'input[type=checkbox][value=games]'
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'renders checkboxes with selected enumerized value' do
|
105
|
+
post.categories << :music
|
106
|
+
|
107
|
+
concat(simple_form_for(post) do |f|
|
108
|
+
f.input(:categories, as: :check_boxes)
|
109
|
+
end)
|
110
|
+
|
111
|
+
assert_select 'input[type=checkbox][value=music][checked=checked]'
|
112
|
+
assert_select 'input[type=checkbox][value=games][checked=checked]', count: 0
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'renders radio buttons with enumerated values' do
|
116
|
+
concat(simple_form_for(user) do |f|
|
117
|
+
f.input(:sex, :as => :radio_buttons)
|
118
|
+
end)
|
119
|
+
|
120
|
+
assert_select 'input[type=radio][value=male]'
|
121
|
+
assert_select 'input[type=radio][value=female]'
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'does not affect not enumerized attributes' do
|
125
|
+
concat(simple_form_for(user) do |f|
|
126
|
+
f.input(:age)
|
127
|
+
end)
|
128
|
+
|
129
|
+
assert_select 'input.string'
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'does not affect not enumerized classes' do
|
133
|
+
concat(simple_form_for(Thing.new) do |f|
|
134
|
+
f.input(:name)
|
135
|
+
end)
|
136
|
+
|
137
|
+
assert_select 'input.string'
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'renders select with enumerized values for non-ActiveModel object' do
|
141
|
+
concat(simple_form_for(Registration.new, as: 'registration', url: '/') do |f|
|
142
|
+
f.input(:sex)
|
143
|
+
end)
|
144
|
+
|
145
|
+
assert_select 'select option[value=male]'
|
146
|
+
assert_select 'select option[value=female]'
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'does not affect forms without object' do
|
150
|
+
concat(simple_form_for('') do |f|
|
151
|
+
f.input(:name)
|
152
|
+
end)
|
153
|
+
|
154
|
+
assert_select 'input.string'
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MockController
|
4
|
+
attr_writer :action_name
|
5
|
+
|
6
|
+
def _routes
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def action_name
|
11
|
+
defined?(@action_name) ? @action_name : "edit"
|
12
|
+
end
|
13
|
+
|
14
|
+
def url_for(*args)
|
15
|
+
"http://example.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
def url_helpers
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def url_options
|
23
|
+
{}
|
24
|
+
end
|
25
|
+
|
26
|
+
def hash_for_users_path(*); end
|
27
|
+
|
28
|
+
def polymorphic_mappings
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
end
|