enumerize 0.8.0 → 2.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -12
- data/CHANGELOG.md +112 -0
- data/Gemfile +5 -22
- data/Gemfile.global +19 -0
- data/Gemfile.mongo_mapper +6 -0
- data/Gemfile.rails42 +6 -0
- data/README.md +185 -9
- data/Rakefile +2 -4
- data/enumerize.gemspec +1 -0
- data/lib/enumerize/activerecord.rb +17 -28
- data/lib/enumerize/attribute.rb +41 -9
- data/lib/enumerize/base.rb +28 -17
- data/lib/enumerize/hooks/formtastic.rb +3 -8
- data/lib/enumerize/hooks/sequel_dataset.rb +15 -0
- data/lib/enumerize/hooks/simple_form.rb +5 -11
- data/lib/enumerize/hooks/uniqueness.rb +3 -8
- data/lib/enumerize/integrations/rspec/matcher.rb +107 -26
- data/lib/enumerize/mongoid.rb +13 -0
- data/lib/enumerize/predicatable.rb +7 -16
- data/lib/enumerize/predicates.rb +3 -1
- data/lib/enumerize/scope/activerecord.rb +37 -0
- data/lib/enumerize/scope/mongoid.rb +35 -0
- data/lib/enumerize/scope/sequel.rb +40 -0
- data/lib/enumerize/sequel.rb +57 -0
- data/lib/enumerize/set.rb +18 -8
- data/lib/enumerize/value.rb +10 -9
- data/lib/enumerize/version.rb +1 -1
- data/lib/enumerize.rb +23 -1
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +258 -0
- data/spec/spec_helper.rb +28 -0
- data/test/activerecord_test.rb +143 -7
- data/test/attribute_test.rb +22 -0
- data/test/base_test.rb +2 -2
- data/test/formtastic_test.rb +3 -12
- data/test/mongo_mapper_test.rb +6 -0
- data/test/mongoid_test.rb +62 -6
- data/test/multiple_test.rb +21 -0
- data/test/predicates_test.rb +6 -0
- data/test/sequel_test.rb +291 -0
- data/test/set_test.rb +14 -0
- data/test/simple_form_test.rb +0 -1
- data/test/support/view_test_helper.rb +4 -0
- data/test/test_helper.rb +23 -2
- data/test/value_test.rb +51 -21
- metadata +39 -9
- data/Gemfile.rails4 +0 -23
- data/lib/enumerize/form_helper.rb +0 -23
- data/test/rspec_matcher_test.rb +0 -76
- data/test/rspec_spec.rb +0 -13
data/test/activerecord_test.rb
CHANGED
@@ -15,13 +15,13 @@ ActiveRecord::Base.connection.instance_eval do
|
|
15
15
|
t.string :lambda_role
|
16
16
|
t.string :name
|
17
17
|
t.string :interests
|
18
|
-
t.
|
18
|
+
t.integer :status
|
19
19
|
t.string :account_type, :default => :basic
|
20
20
|
end
|
21
21
|
|
22
22
|
create_table :documents do |t|
|
23
23
|
t.string :visibility
|
24
|
-
t.timestamps
|
24
|
+
t.timestamps null: true
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -53,10 +53,19 @@ class User < ActiveRecord::Base
|
|
53
53
|
enumerize :status, :in => { active: 1, blocked: 2 }, scope: true
|
54
54
|
|
55
55
|
enumerize :account_type, :in => [:basic, :premium]
|
56
|
+
|
57
|
+
# There is no column for relationship enumeration for testing purposes: model
|
58
|
+
# should not be broken even if the associated column does not exist yet.
|
59
|
+
enumerize :relationship, :in => [:single, :married]
|
56
60
|
end
|
57
61
|
|
58
62
|
class UniqStatusUser < User
|
59
63
|
validates :status, uniqueness: true
|
64
|
+
validates :sex, presence: true
|
65
|
+
end
|
66
|
+
|
67
|
+
class InterestsRequiredUser < User
|
68
|
+
validates :interests, presence: true
|
60
69
|
end
|
61
70
|
|
62
71
|
describe Enumerize::ActiveRecordSupport do
|
@@ -92,7 +101,8 @@ describe Enumerize::ActiveRecordSupport do
|
|
92
101
|
it 'does not set default value for not selected attributes' do
|
93
102
|
User.delete_all
|
94
103
|
User.create!(:sex => :male)
|
95
|
-
|
104
|
+
|
105
|
+
assert_equal ['id'], User.select(:id).first.attributes.keys
|
96
106
|
end
|
97
107
|
|
98
108
|
it 'has default value with lambda' do
|
@@ -128,9 +138,18 @@ describe Enumerize::ActiveRecordSupport do
|
|
128
138
|
user.errors[:role].must_include 'is not included in the list'
|
129
139
|
end
|
130
140
|
|
131
|
-
it 'validates inclusion when using write_attribute' do
|
141
|
+
it 'validates inclusion when using write_attribute with string attribute' do
|
142
|
+
user = User.new
|
143
|
+
user.send(:write_attribute, 'role', 'wrong')
|
144
|
+
user.read_attribute_for_validation(:role).must_equal 'wrong'
|
145
|
+
user.wont_be :valid?
|
146
|
+
user.errors[:role].must_include 'is not included in the list'
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'validates inclusion when using write_attribute with symbol attribute' do
|
132
150
|
user = User.new
|
133
151
|
user.send(:write_attribute, :role, 'wrong')
|
152
|
+
user.read_attribute_for_validation(:role).must_equal 'wrong'
|
134
153
|
user.wont_be :valid?
|
135
154
|
user.errors[:role].must_include 'is not included in the list'
|
136
155
|
end
|
@@ -143,7 +162,7 @@ describe Enumerize::ActiveRecordSupport do
|
|
143
162
|
|
144
163
|
it "uses persisted value for validation if it hasn't been set" do
|
145
164
|
user = User.create! :sex => :male
|
146
|
-
User.find(user).read_attribute_for_validation(:sex).must_equal 'male'
|
165
|
+
User.find(user.id).read_attribute_for_validation(:sex).must_equal 'male'
|
147
166
|
end
|
148
167
|
|
149
168
|
it 'is valid with empty string assigned' do
|
@@ -179,6 +198,13 @@ describe Enumerize::ActiveRecordSupport do
|
|
179
198
|
interests.must_equal %w(music dancing)
|
180
199
|
end
|
181
200
|
|
201
|
+
it 'stores multiple value passed passed to new' do
|
202
|
+
user = User.new(interests: [:music, :dancing])
|
203
|
+
user.save!
|
204
|
+
user.interests.must_equal %w(music dancing)
|
205
|
+
User.find(user.id).interests.must_equal %w(music dancing)
|
206
|
+
end
|
207
|
+
|
182
208
|
it 'returns invalid multiple value for validation' do
|
183
209
|
user = User.new
|
184
210
|
user.interests << :music
|
@@ -199,6 +225,22 @@ describe Enumerize::ActiveRecordSupport do
|
|
199
225
|
user.must_be :valid?
|
200
226
|
end
|
201
227
|
|
228
|
+
it 'stores custom values for multiple attributes' do
|
229
|
+
User.delete_all
|
230
|
+
|
231
|
+
klass = Class.new(User)
|
232
|
+
klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
|
233
|
+
|
234
|
+
user = klass.new
|
235
|
+
user.interests << :music
|
236
|
+
user.read_attribute(:interests).must_equal [0]
|
237
|
+
user.interests.must_equal %w(music)
|
238
|
+
user.save
|
239
|
+
|
240
|
+
user = klass.find(user.id)
|
241
|
+
user.interests.must_equal %w(music)
|
242
|
+
end
|
243
|
+
|
202
244
|
it 'adds scope' do
|
203
245
|
User.delete_all
|
204
246
|
|
@@ -215,6 +257,12 @@ describe Enumerize::ActiveRecordSupport do
|
|
215
257
|
User.having_role(:admin).must_equal [user_1]
|
216
258
|
end
|
217
259
|
|
260
|
+
it 'ignores not enumerized values that passed to the scope method' do
|
261
|
+
User.delete_all
|
262
|
+
|
263
|
+
User.with_status(:foo).must_equal []
|
264
|
+
end
|
265
|
+
|
218
266
|
it 'allows either key or value as valid' do
|
219
267
|
user_1 = User.new(status: :active)
|
220
268
|
user_2 = User.new(status: 1)
|
@@ -258,6 +306,36 @@ describe Enumerize::ActiveRecordSupport do
|
|
258
306
|
user.errors[:status].wont_be :empty?
|
259
307
|
end
|
260
308
|
|
309
|
+
it 'validates presence with multiple attributes' do
|
310
|
+
user = InterestsRequiredUser.new
|
311
|
+
user.interests = []
|
312
|
+
user.valid?
|
313
|
+
|
314
|
+
user.errors[:interests].wont_be :empty?
|
315
|
+
|
316
|
+
user.interests = ['']
|
317
|
+
user.valid?
|
318
|
+
|
319
|
+
user.errors[:interests].wont_be :empty?
|
320
|
+
|
321
|
+
user.interests = [:dancing, :programming]
|
322
|
+
user.valid?
|
323
|
+
|
324
|
+
user.errors[:interests].must_be_empty
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'is valid after #becomes' do
|
328
|
+
User.delete_all
|
329
|
+
user = User.new
|
330
|
+
user.sex = :male
|
331
|
+
user.save!
|
332
|
+
|
333
|
+
uniq_user = User.find(user.id).becomes(UniqStatusUser)
|
334
|
+
uniq_user.valid?
|
335
|
+
|
336
|
+
uniq_user.errors.must_be_empty
|
337
|
+
end
|
338
|
+
|
261
339
|
it 'supports multiple attributes in #becomes' do
|
262
340
|
User.delete_all
|
263
341
|
|
@@ -291,7 +369,65 @@ describe Enumerize::ActiveRecordSupport do
|
|
291
369
|
user = User.create(:status => :active)
|
292
370
|
user.status = :blocked
|
293
371
|
|
294
|
-
|
295
|
-
|
372
|
+
assert_equal [1, 2], YAML.load(user.changes.to_yaml)[:status]
|
373
|
+
end
|
374
|
+
|
375
|
+
it 'allows using update_all' do
|
376
|
+
User.delete_all
|
377
|
+
|
378
|
+
user = User.create(status: :active, account_type: :premium)
|
379
|
+
|
380
|
+
User.update_all(status: :blocked)
|
381
|
+
user.reload
|
382
|
+
user.status.must_equal 'blocked'
|
383
|
+
|
384
|
+
User.update_all(status: :active, account_type: :basic)
|
385
|
+
user.reload
|
386
|
+
user.status.must_equal 'active'
|
387
|
+
user.account_type.must_equal 'basic'
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'allows using update_all for multiple enumerize' do
|
391
|
+
User.delete_all
|
392
|
+
|
393
|
+
klass = Class.new(User)
|
394
|
+
klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
|
395
|
+
|
396
|
+
user = klass.create(status: :active)
|
397
|
+
klass.update_all(status: :blocked, interests: [:music, :dancing])
|
398
|
+
|
399
|
+
user = klass.find(user.id)
|
400
|
+
user.status.must_equal 'blocked'
|
401
|
+
user.interests.must_equal %w(music dancing)
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'allows using update_all with values' do
|
405
|
+
User.delete_all
|
406
|
+
|
407
|
+
user = User.create(status: :active)
|
408
|
+
|
409
|
+
User.update_all(status: 2)
|
410
|
+
user.reload
|
411
|
+
user.status.must_equal 'blocked'
|
412
|
+
end
|
413
|
+
|
414
|
+
it 'preserves string usage of update_all' do
|
415
|
+
User.delete_all
|
416
|
+
|
417
|
+
user = User.create(name: "Fred")
|
418
|
+
|
419
|
+
User.update_all("name = 'Frederick'")
|
420
|
+
user.reload
|
421
|
+
user.name.must_equal 'Frederick'
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'preserves interpolated array usage of update_all' do
|
425
|
+
User.delete_all
|
426
|
+
|
427
|
+
user = User.create(name: "Fred")
|
428
|
+
|
429
|
+
User.update_all(["name = :name", {name: 'Frederick'}])
|
430
|
+
user.reload
|
431
|
+
user.name.must_equal 'Frederick'
|
296
432
|
end
|
297
433
|
end
|
data/test/attribute_test.rb
CHANGED
@@ -19,6 +19,12 @@ describe Enumerize::Attribute do
|
|
19
19
|
attr.name.must_equal :foo
|
20
20
|
end
|
21
21
|
|
22
|
+
it 'uses custom value class' do
|
23
|
+
value_class = Class.new(Enumerize::Value)
|
24
|
+
build_attr nil, 'foo', :in => %w[a b], :value_class => value_class
|
25
|
+
attr.values.first.must_be_instance_of value_class
|
26
|
+
end
|
27
|
+
|
22
28
|
describe 'i18n scopes' do
|
23
29
|
it 'returns scopes from options' do
|
24
30
|
build_attr nil, 'foo', :in => %w[a b], :i18n_scope => %w[bar buzz]
|
@@ -79,6 +85,18 @@ describe Enumerize::Attribute do
|
|
79
85
|
end
|
80
86
|
end
|
81
87
|
|
88
|
+
it 'sets up shortcut methods for each value' do
|
89
|
+
build_attr nil, :foo, :in => {:a => 1, :b => 2}
|
90
|
+
|
91
|
+
attr.must_respond_to :a
|
92
|
+
attr.must_respond_to :b
|
93
|
+
|
94
|
+
attr.a.value.must_equal 1
|
95
|
+
attr.b.value.must_equal 2
|
96
|
+
attr.a.text.must_equal 'A'
|
97
|
+
attr.b.text.must_equal 'B'
|
98
|
+
end
|
99
|
+
|
82
100
|
describe 'values hash with zero' do
|
83
101
|
before do
|
84
102
|
build_attr nil, :foo, :in => {:a => 1, :b => 2, :c => 0}
|
@@ -93,6 +111,10 @@ describe Enumerize::Attribute do
|
|
93
111
|
attr.find_value(2).must_equal 'b'
|
94
112
|
attr.find_value(0).must_equal 'c'
|
95
113
|
end
|
114
|
+
|
115
|
+
it 'finds all values by hash values' do
|
116
|
+
attr.find_values(1, 2, 0).must_equal ['a', 'b', 'c']
|
117
|
+
end
|
96
118
|
end
|
97
119
|
|
98
120
|
describe 'boolean values hash' do
|
data/test/base_test.rb
CHANGED
@@ -41,7 +41,7 @@ describe Enumerize::Base do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
it 'scopes translation by
|
44
|
+
it 'scopes translation by i18n key' do
|
45
45
|
def klass.model_name
|
46
46
|
name = "ExampleClass"
|
47
47
|
def name.i18n_key
|
@@ -171,7 +171,7 @@ describe Enumerize::Base do
|
|
171
171
|
|
172
172
|
object = klass.new
|
173
173
|
object.foo.must_be_nil
|
174
|
-
object.attributes.must_equal({
|
174
|
+
object.attributes.must_equal({})
|
175
175
|
|
176
176
|
object.foo = 'test'
|
177
177
|
object.foo.must_equal 'test'
|
data/test/formtastic_test.rb
CHANGED
@@ -1,16 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
module Helpers
|
6
|
-
module InputHelper
|
7
|
-
remove_method :input_class
|
8
|
-
def input_class(as)
|
9
|
-
input_class_with_const_defined(as)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
2
|
+
|
3
|
+
Formtastic::FormBuilder.action_class_finder = Formtastic::ActionClassFinder
|
4
|
+
Formtastic::FormBuilder.input_class_finder = Formtastic::InputClassFinder
|
14
5
|
|
15
6
|
class FormtasticSpec < MiniTest::Spec
|
16
7
|
include ViewTestHelper
|
data/test/mongo_mapper_test.rb
CHANGED
data/test/mongoid_test.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
+
begin
|
4
|
+
|
3
5
|
silence_warnings do
|
4
6
|
require 'mongoid'
|
5
7
|
end
|
6
8
|
|
7
9
|
Mongoid.configure do |config|
|
8
|
-
config.
|
9
|
-
config.
|
10
|
-
config.include_root_in_json = true
|
10
|
+
config.connect_to('enumerize-test-suite')
|
11
|
+
config.options = { use_utc: true, include_root_in_json: true }
|
11
12
|
end
|
12
13
|
|
13
14
|
describe Enumerize do
|
@@ -17,9 +18,10 @@ describe Enumerize do
|
|
17
18
|
|
18
19
|
field :sex
|
19
20
|
field :role
|
20
|
-
enumerize :sex,
|
21
|
-
enumerize :
|
22
|
-
enumerize :
|
21
|
+
enumerize :sex, :in => %w[male female], scope: true
|
22
|
+
enumerize :status, :in => %w[notice warning error], scope: true
|
23
|
+
enumerize :role, :in => %w[admin user], :default => 'user', scope: :having_role
|
24
|
+
enumerize :mult, :in => %w[one two three four], :multiple => true
|
23
25
|
end
|
24
26
|
|
25
27
|
before { $VERBOSE = nil }
|
@@ -55,6 +57,21 @@ describe Enumerize do
|
|
55
57
|
model.new.role.must_equal 'user'
|
56
58
|
end
|
57
59
|
|
60
|
+
it 'uses after_initialize callback to set default value' do
|
61
|
+
model.delete_all
|
62
|
+
model.create!(sex: 'male', role: nil)
|
63
|
+
|
64
|
+
user = model.where(sex: 'male').first
|
65
|
+
user.role.must_equal 'user'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'does not set default value for not selected attributes' do
|
69
|
+
model.delete_all
|
70
|
+
model.create!(sex: :male)
|
71
|
+
|
72
|
+
assert_equal ['_id'], model.only(:id).first.attributes.keys
|
73
|
+
end
|
74
|
+
|
58
75
|
it 'validates inclusion' do
|
59
76
|
user = model.new
|
60
77
|
user.role = 'wrong'
|
@@ -76,4 +93,43 @@ describe Enumerize do
|
|
76
93
|
user = model.first
|
77
94
|
user.mult.to_a.must_equal ['one', 'two']
|
78
95
|
end
|
96
|
+
|
97
|
+
it 'adds scope' do
|
98
|
+
model.delete_all
|
99
|
+
|
100
|
+
user_1 = model.create!(sex: :male, role: :admin)
|
101
|
+
user_2 = model.create!(sex: :female, role: :user)
|
102
|
+
|
103
|
+
model.with_sex(:male).to_a.must_equal [user_1]
|
104
|
+
model.with_sex(:female).to_a.must_equal [user_2]
|
105
|
+
model.with_sex(:male, :female).to_set.must_equal [user_1, user_2].to_set
|
106
|
+
|
107
|
+
model.without_sex(:male).to_a.must_equal [user_2]
|
108
|
+
model.without_sex(:female).to_a.must_equal [user_1]
|
109
|
+
model.without_sex(:male, :female).to_a.must_equal []
|
110
|
+
|
111
|
+
model.having_role(:admin).to_a.must_equal [user_1]
|
112
|
+
model.having_role(:user).to_a.must_equal [user_2]
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'chains scopes' do
|
116
|
+
model.delete_all
|
117
|
+
|
118
|
+
user_1 = model.create!(status: :notice)
|
119
|
+
user_2 = model.create!(status: :warning)
|
120
|
+
user_3 = model.create!(status: :error)
|
121
|
+
|
122
|
+
model.with_status(:notice, :warning).with_status(:notice, :error).to_a.must_equal [user_1]
|
123
|
+
model.with_status(:notice, :warning).union.with_status(:notice, :error).to_a.must_equal [user_1, user_2, user_3]
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'ignores not enumerized values that passed to the scope method' do
|
127
|
+
model.delete_all
|
128
|
+
|
129
|
+
model.with_sex(:foo).must_equal []
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
rescue LoadError
|
134
|
+
# Skip
|
79
135
|
end
|
data/test/multiple_test.rb
CHANGED
@@ -24,6 +24,21 @@ describe Enumerize::Base do
|
|
24
24
|
object.foos.must_equal %w(a c)
|
25
25
|
end
|
26
26
|
|
27
|
+
it 'sets default value as single value' do
|
28
|
+
klass.enumerize :foos, in: %w(a b c), default: 'b', multiple: true
|
29
|
+
object.foos.must_equal %w(b)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'sets default value as array of one element' do
|
33
|
+
klass.enumerize :foos, in: %w(a b c), default: %w(b), multiple: true
|
34
|
+
object.foos.must_equal %w(b)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'sets default value as array of several elements' do
|
38
|
+
klass.enumerize :foos, in: %w(a b c), default: %w(b c), multiple: true
|
39
|
+
object.foos.must_equal %w(b c)
|
40
|
+
end
|
41
|
+
|
27
42
|
it "doesn't define _text method" do
|
28
43
|
klass.enumerize :foos, in: %w(a b c), multiple: true
|
29
44
|
object.wont_respond_to :foos_text
|
@@ -33,4 +48,10 @@ describe Enumerize::Base do
|
|
33
48
|
klass.enumerize :foos, in: %w(a b c), multiple: true
|
34
49
|
object.wont_respond_to :foos_value
|
35
50
|
end
|
51
|
+
|
52
|
+
it "cannot define multiple with scope" do
|
53
|
+
assert_raises ArgumentError do
|
54
|
+
klass.enumerize :foos, in: %w(a b c), multiple: true, scope: true
|
55
|
+
end
|
56
|
+
end
|
36
57
|
end
|
data/test/predicates_test.rb
CHANGED
@@ -15,6 +15,12 @@ describe Enumerize::Predicates do
|
|
15
15
|
object.must_respond_to :b?
|
16
16
|
end
|
17
17
|
|
18
|
+
it 'creates predicate methods when enumerized values have dash in it' do
|
19
|
+
klass.enumerize(:foo, in: %w(foo-bar bar-foo), predicates: true)
|
20
|
+
object.must_respond_to :foo_bar?
|
21
|
+
object.must_respond_to :bar_foo?
|
22
|
+
end
|
23
|
+
|
18
24
|
it 'creates predicate methods on multiple attribute' do
|
19
25
|
klass.enumerize(:foo, in: %w(a b), predicates: true, multiple: true)
|
20
26
|
object.must_respond_to :a?
|