enumerize 2.0.0 → 2.7.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 +5 -5
- data/.github/workflows/ruby.yml +75 -0
- data/CHANGELOG.md +117 -3
- data/Gemfile +3 -3
- data/Gemfile.global +5 -9
- data/Gemfile.mongo_mapper +2 -2
- data/Gemfile.rails60 +6 -0
- data/Gemfile.rails61 +6 -0
- data/Gemfile.rails70 +9 -0
- data/Gemfile.railsmaster +5 -0
- data/README.md +210 -92
- data/Rakefile +9 -3
- data/enumerize.gemspec +1 -1
- data/lib/enumerize/activemodel.rb +47 -0
- data/lib/enumerize/activerecord.rb +92 -6
- data/lib/enumerize/attribute.rb +19 -11
- data/lib/enumerize/attribute_map.rb +2 -0
- data/lib/enumerize/base.rb +22 -18
- data/lib/enumerize/hooks/formtastic.rb +4 -1
- data/lib/enumerize/hooks/sequel_dataset.rb +2 -0
- data/lib/enumerize/hooks/simple_form.rb +4 -1
- data/lib/enumerize/hooks/uniqueness.rb +5 -1
- data/lib/enumerize/integrations/rails_admin.rb +3 -1
- data/lib/enumerize/integrations/rspec/matcher.rb +7 -2
- data/lib/enumerize/integrations/rspec.rb +3 -0
- data/lib/enumerize/module.rb +2 -0
- data/lib/enumerize/module_attributes.rb +2 -0
- data/lib/enumerize/mongoid.rb +23 -0
- data/lib/enumerize/predicatable.rb +3 -1
- data/lib/enumerize/predicates.rb +16 -0
- data/lib/enumerize/scope/activerecord.rb +16 -0
- data/lib/enumerize/scope/mongoid.rb +15 -0
- data/lib/enumerize/scope/sequel.rb +16 -0
- data/lib/enumerize/sequel.rb +9 -4
- data/lib/enumerize/set.rb +2 -0
- data/lib/enumerize/utils.rb +12 -0
- data/lib/enumerize/value.rb +14 -15
- data/lib/enumerize/version.rb +3 -1
- data/lib/enumerize.rb +9 -0
- data/lib/sequel/plugins/enumerize.rb +18 -0
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +13 -10
- data/spec/spec_helper.rb +2 -0
- data/test/activemodel_test.rb +114 -0
- data/test/activerecord_test.rb +327 -78
- data/test/attribute_map_test.rb +9 -7
- data/test/attribute_test.rb +37 -34
- data/test/base_test.rb +117 -65
- data/test/formtastic_test.rb +25 -0
- data/test/module_attributes_test.rb +10 -8
- data/test/mongo_mapper_test.rb +20 -11
- data/test/mongoid_test.rb +52 -23
- data/test/multiple_test.rb +27 -19
- data/test/predicates_test.rb +51 -29
- data/test/rails_admin_test.rb +8 -6
- data/test/sequel_test.rb +228 -177
- data/test/set_test.rb +29 -27
- data/test/simple_form_test.rb +25 -0
- data/test/support/mock_controller.rb +6 -0
- data/test/support/shared_enums.rb +43 -0
- data/test/support/view_test_helper.rb +14 -1
- data/test/test_helper.rb +10 -0
- data/test/value_test.rb +59 -31
- metadata +16 -7
- data/.travis.yml +0 -18
- data/Gemfile.rails42 +0 -6
data/lib/enumerize/value.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'i18n'
|
4
|
+
require 'active_support/inflector'
|
2
5
|
|
3
6
|
module Enumerize
|
4
7
|
class Value < String
|
@@ -11,10 +14,20 @@ module Enumerize
|
|
11
14
|
@value = value.nil? ? name.to_s : value
|
12
15
|
|
13
16
|
super(name.to_s)
|
17
|
+
|
18
|
+
@i18n_keys = @attr.i18n_scopes.map do |s|
|
19
|
+
scope = Utils.call_if_callable(s, @value)
|
20
|
+
|
21
|
+
:"#{scope}.#{self}"
|
22
|
+
end
|
23
|
+
@i18n_keys << :"enumerize.defaults.#{@attr.name}.#{self}"
|
24
|
+
@i18n_keys << :"enumerize.#{@attr.name}.#{self}"
|
25
|
+
@i18n_keys << ActiveSupport::Inflector.humanize(ActiveSupport::Inflector.underscore(self)) # humanize value if there are no translations
|
26
|
+
@i18n_keys
|
14
27
|
end
|
15
28
|
|
16
29
|
def text
|
17
|
-
I18n.t(i18n_keys[0], :default => i18n_keys[1..-1])
|
30
|
+
I18n.t(@i18n_keys[0], :default => @i18n_keys[1..-1]) if @i18n_keys
|
18
31
|
end
|
19
32
|
|
20
33
|
def ==(other)
|
@@ -30,19 +43,5 @@ module Enumerize
|
|
30
43
|
def predicate_call(value)
|
31
44
|
value == self
|
32
45
|
end
|
33
|
-
|
34
|
-
def i18n_keys
|
35
|
-
@i18n_keys ||= begin
|
36
|
-
i18n_keys = i18n_scopes
|
37
|
-
i18n_keys << :"enumerize.defaults.#{@attr.name}.#{self}"
|
38
|
-
i18n_keys << :"enumerize.#{@attr.name}.#{self}"
|
39
|
-
i18n_keys << self.underscore.humanize # humanize value if there are no translations
|
40
|
-
i18n_keys
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def i18n_scopes
|
45
|
-
@attr.i18n_scopes.map { |s| :"#{s}.#{self}" }
|
46
|
-
end
|
47
46
|
end
|
48
47
|
end
|
data/lib/enumerize/version.rb
CHANGED
data/lib/enumerize.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/concern'
|
4
|
+
require 'active_support/core_ext/object/blank'
|
2
5
|
require 'enumerize/version'
|
3
6
|
|
4
7
|
module Enumerize
|
@@ -10,8 +13,10 @@ module Enumerize
|
|
10
13
|
autoload :Module, 'enumerize/module'
|
11
14
|
autoload :Predicates, 'enumerize/predicates'
|
12
15
|
autoload :Predicatable, 'enumerize/predicatable'
|
16
|
+
autoload :Utils, 'enumerize/utils'
|
13
17
|
autoload :ModuleAttributes, 'enumerize/module_attributes'
|
14
18
|
|
19
|
+
autoload :ActiveModelAttributesSupport, 'enumerize/activemodel'
|
15
20
|
autoload :ActiveRecordSupport, 'enumerize/activerecord'
|
16
21
|
autoload :SequelSupport, 'enumerize/sequel'
|
17
22
|
autoload :MongoidSupport, 'enumerize/mongoid'
|
@@ -31,6 +36,10 @@ module Enumerize
|
|
31
36
|
base.send :include, Enumerize::Base
|
32
37
|
base.extend Enumerize::Predicates
|
33
38
|
|
39
|
+
if defined?(::ActiveModel::Attributes)
|
40
|
+
base.extend Enumerize::ActiveModelAttributesSupport
|
41
|
+
end
|
42
|
+
|
34
43
|
if defined?(::ActiveRecord::Base)
|
35
44
|
base.extend Enumerize::ActiveRecordSupport
|
36
45
|
base.extend Enumerize::Scope::ActiveRecord
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module Plugins
|
5
|
+
module Enumerize
|
6
|
+
# Depend on the def_dataset_method plugin
|
7
|
+
def self.apply(model)
|
8
|
+
model.plugin(:def_dataset_method) unless model.respond_to?(:def_dataset_method)
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
def self.included(base)
|
13
|
+
base.extend ::Enumerize
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_record'
|
2
4
|
|
3
5
|
silence_warnings do
|
@@ -11,6 +13,7 @@ ActiveRecord::Base.connection.instance_eval do
|
|
11
13
|
t.string :sex
|
12
14
|
t.string :role
|
13
15
|
t.string :account_type
|
16
|
+
t.string :status
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
@@ -20,6 +23,7 @@ class User < ActiveRecord::Base
|
|
20
23
|
enumerize :sex, :in => [:male, :female], scope: true
|
21
24
|
enumerize :role, :in => [:user, :admin], scope: :having_role
|
22
25
|
enumerize :account_type, :in => [:basic, :premium]
|
26
|
+
enumerize :status, :in => [:active, :disabled], scope: :shallow
|
23
27
|
end
|
24
28
|
|
25
29
|
RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
@@ -39,7 +43,6 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
39
43
|
end
|
40
44
|
|
41
45
|
describe 'without qualifier' do
|
42
|
-
|
43
46
|
it 'accepts when has defined a enumerize' do
|
44
47
|
model.enumerize(:sex, :in => [:male, :female])
|
45
48
|
expect(subject).to enumerize(:sex)
|
@@ -54,9 +57,7 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
54
57
|
end
|
55
58
|
|
56
59
|
describe '#in' do
|
57
|
-
|
58
60
|
context 'defined as array' do
|
59
|
-
|
60
61
|
before do
|
61
62
|
model.enumerize(:sex, :in => [:male, :female])
|
62
63
|
end
|
@@ -89,7 +90,6 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
89
90
|
end
|
90
91
|
|
91
92
|
context 'defined as hash' do
|
92
|
-
|
93
93
|
before do
|
94
94
|
model.enumerize(:sex, :in => { male: 0, female: 1 })
|
95
95
|
end
|
@@ -128,7 +128,6 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
128
128
|
end
|
129
129
|
|
130
130
|
describe '#with_default' do
|
131
|
-
|
132
131
|
before do
|
133
132
|
model.enumerize(:sex, :in => [:male, :female], default: :female)
|
134
133
|
end
|
@@ -159,9 +158,7 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
159
158
|
end
|
160
159
|
|
161
160
|
describe '#with_i18n_scope' do
|
162
|
-
|
163
161
|
context 'defined as string' do
|
164
|
-
|
165
162
|
before do
|
166
163
|
model.enumerize(:sex, :in => [:male, :female], i18n_scope: 'sex')
|
167
164
|
end
|
@@ -198,7 +195,6 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
198
195
|
end
|
199
196
|
|
200
197
|
describe '#with_predicates' do
|
201
|
-
|
202
198
|
it 'accepts when predicates is defined as a boolean' do
|
203
199
|
model.enumerize(:sex, :in => [:male, :female], predicates: true)
|
204
200
|
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(true)
|
@@ -209,6 +205,11 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
209
205
|
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(prefix: true)
|
210
206
|
end
|
211
207
|
|
208
|
+
it 'accepts when custom values are used as attribute' do
|
209
|
+
model.enumerize(:sex, :in => { male: 0, female: 1 }, predicates: true)
|
210
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(true)
|
211
|
+
end
|
212
|
+
|
212
213
|
it 'rejects when predicates is not defined' do
|
213
214
|
model.enumerize(:sex, :in => [:male, :female])
|
214
215
|
message = 'Expected Model to define enumerize :sex in: "female", "male" predicates: true'
|
@@ -219,7 +220,6 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
219
220
|
end
|
220
221
|
|
221
222
|
describe '#with_multiple' do
|
222
|
-
|
223
223
|
it 'accepts when has defined the multiple' do
|
224
224
|
model.enumerize(:sex, :in => [:male, :female], multiple: true)
|
225
225
|
expect(subject).to enumerize(:sex).in(:male, :female).with_multiple(true)
|
@@ -235,7 +235,6 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
235
235
|
end
|
236
236
|
|
237
237
|
describe '#with_scope' do
|
238
|
-
|
239
238
|
subject do
|
240
239
|
User.new
|
241
240
|
end
|
@@ -248,6 +247,10 @@ RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
|
248
247
|
expect(subject).to enumerize(:role).in(:user, :admin).with_scope(scope: :having_role)
|
249
248
|
end
|
250
249
|
|
250
|
+
it 'accepts shallow scope' do
|
251
|
+
expect(subject).to enumerize(:status).in(:active, :disabled).with_scope(:shallow)
|
252
|
+
end
|
253
|
+
|
251
254
|
it 'rejects when scope is not defined' do
|
252
255
|
message = 'Expected User to define enumerize :account_type in: "basic", "premium" scope: true'
|
253
256
|
expect do
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
if defined?(::ActiveModel::Attributes)
|
6
|
+
|
7
|
+
class ActiveModelTest < MiniTest::Spec
|
8
|
+
class ActiveModelUser
|
9
|
+
include ActiveModel::Model
|
10
|
+
include ActiveModel::Attributes
|
11
|
+
extend Enumerize
|
12
|
+
|
13
|
+
attribute :name, :string
|
14
|
+
enumerize :sex, :in => %w[male female]
|
15
|
+
enumerize :role, :in => %w[admin user], :default => 'user'
|
16
|
+
enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true
|
17
|
+
end
|
18
|
+
|
19
|
+
class InterestsRequiredActiveModelUser < ActiveModelUser
|
20
|
+
validates :interests, presence: true
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:model) { ActiveModelUser }
|
24
|
+
|
25
|
+
it 'initialize value' do
|
26
|
+
user = model.new(:name => 'active_model_user', :sex => :male, :role => :user, :interests => [:music, :programming])
|
27
|
+
expect(user.sex).must_equal 'male'
|
28
|
+
expect(user.sex_text).must_equal 'Male'
|
29
|
+
expect(user.role).must_equal 'user'
|
30
|
+
expect(user.role_text).must_equal 'User'
|
31
|
+
expect(user.interests).must_equal %w(music programming)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'sets nil if invalid value is passed' do
|
35
|
+
user = model.new
|
36
|
+
user.sex = :invalid
|
37
|
+
expect(user.sex).must_be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'stores value' do
|
41
|
+
user = model.new
|
42
|
+
user.sex = :female
|
43
|
+
expect(user.sex).must_equal 'female'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'has default value' do
|
47
|
+
expect(model.new.role).must_equal 'user'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'validates inclusion' do
|
51
|
+
user = model.new
|
52
|
+
user.role = 'wrong'
|
53
|
+
expect(user).wont_be :valid?
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'supports multiple attributes' do
|
57
|
+
user = ActiveModelUser.new
|
58
|
+
expect(user.interests).must_be_instance_of Enumerize::Set
|
59
|
+
expect(user.interests).must_be_empty
|
60
|
+
user.interests << :music
|
61
|
+
expect(user.interests).must_equal %w(music)
|
62
|
+
user.interests << :sports
|
63
|
+
expect(user.interests).must_equal %w(music sports)
|
64
|
+
|
65
|
+
user.interests = []
|
66
|
+
interests = user.interests
|
67
|
+
interests << :music
|
68
|
+
expect(interests).must_equal %w(music)
|
69
|
+
interests << :dancing
|
70
|
+
expect(interests).must_equal %w(music dancing)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns invalid multiple value for validation' do
|
74
|
+
user = ActiveModelUser.new
|
75
|
+
user.interests << :music
|
76
|
+
user.interests << :invalid
|
77
|
+
values = user.read_attribute_for_validation(:interests)
|
78
|
+
expect(values).must_equal %w(music invalid)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'validates multiple attributes' do
|
82
|
+
user = ActiveModelUser.new
|
83
|
+
user.interests << :invalid
|
84
|
+
expect(user).wont_be :valid?
|
85
|
+
|
86
|
+
user.interests = Object.new
|
87
|
+
expect(user).wont_be :valid?
|
88
|
+
|
89
|
+
user.interests = ['music', '']
|
90
|
+
expect(user).must_be :valid?
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'validates presence with multiple attributes' do
|
94
|
+
user = InterestsRequiredActiveModelUser.new
|
95
|
+
user.interests = []
|
96
|
+
user.valid?
|
97
|
+
|
98
|
+
expect(user.errors[:interests]).wont_be :empty?
|
99
|
+
|
100
|
+
user.interests = ['']
|
101
|
+
user.valid?
|
102
|
+
|
103
|
+
expect(user.errors[:interests]).wont_be :empty?
|
104
|
+
|
105
|
+
user.interests = [:dancing, :programming]
|
106
|
+
user.valid?
|
107
|
+
|
108
|
+
expect(user.errors[:interests]).must_be_empty
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
else
|
113
|
+
# Skip
|
114
|
+
end
|