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.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +75 -0
  3. data/CHANGELOG.md +117 -3
  4. data/Gemfile +3 -3
  5. data/Gemfile.global +5 -9
  6. data/Gemfile.mongo_mapper +2 -2
  7. data/Gemfile.rails60 +6 -0
  8. data/Gemfile.rails61 +6 -0
  9. data/Gemfile.rails70 +9 -0
  10. data/Gemfile.railsmaster +5 -0
  11. data/README.md +210 -92
  12. data/Rakefile +9 -3
  13. data/enumerize.gemspec +1 -1
  14. data/lib/enumerize/activemodel.rb +47 -0
  15. data/lib/enumerize/activerecord.rb +92 -6
  16. data/lib/enumerize/attribute.rb +19 -11
  17. data/lib/enumerize/attribute_map.rb +2 -0
  18. data/lib/enumerize/base.rb +22 -18
  19. data/lib/enumerize/hooks/formtastic.rb +4 -1
  20. data/lib/enumerize/hooks/sequel_dataset.rb +2 -0
  21. data/lib/enumerize/hooks/simple_form.rb +4 -1
  22. data/lib/enumerize/hooks/uniqueness.rb +5 -1
  23. data/lib/enumerize/integrations/rails_admin.rb +3 -1
  24. data/lib/enumerize/integrations/rspec/matcher.rb +7 -2
  25. data/lib/enumerize/integrations/rspec.rb +3 -0
  26. data/lib/enumerize/module.rb +2 -0
  27. data/lib/enumerize/module_attributes.rb +2 -0
  28. data/lib/enumerize/mongoid.rb +23 -0
  29. data/lib/enumerize/predicatable.rb +3 -1
  30. data/lib/enumerize/predicates.rb +16 -0
  31. data/lib/enumerize/scope/activerecord.rb +16 -0
  32. data/lib/enumerize/scope/mongoid.rb +15 -0
  33. data/lib/enumerize/scope/sequel.rb +16 -0
  34. data/lib/enumerize/sequel.rb +9 -4
  35. data/lib/enumerize/set.rb +2 -0
  36. data/lib/enumerize/utils.rb +12 -0
  37. data/lib/enumerize/value.rb +14 -15
  38. data/lib/enumerize/version.rb +3 -1
  39. data/lib/enumerize.rb +9 -0
  40. data/lib/sequel/plugins/enumerize.rb +18 -0
  41. data/spec/enumerize/integrations/rspec/matcher_spec.rb +13 -10
  42. data/spec/spec_helper.rb +2 -0
  43. data/test/activemodel_test.rb +114 -0
  44. data/test/activerecord_test.rb +327 -78
  45. data/test/attribute_map_test.rb +9 -7
  46. data/test/attribute_test.rb +37 -34
  47. data/test/base_test.rb +117 -65
  48. data/test/formtastic_test.rb +25 -0
  49. data/test/module_attributes_test.rb +10 -8
  50. data/test/mongo_mapper_test.rb +20 -11
  51. data/test/mongoid_test.rb +52 -23
  52. data/test/multiple_test.rb +27 -19
  53. data/test/predicates_test.rb +51 -29
  54. data/test/rails_admin_test.rb +8 -6
  55. data/test/sequel_test.rb +228 -177
  56. data/test/set_test.rb +29 -27
  57. data/test/simple_form_test.rb +25 -0
  58. data/test/support/mock_controller.rb +6 -0
  59. data/test/support/shared_enums.rb +43 -0
  60. data/test/support/view_test_helper.rb +14 -1
  61. data/test/test_helper.rb +10 -0
  62. data/test/value_test.rb +59 -31
  63. metadata +16 -7
  64. data/.travis.yml +0 -18
  65. data/Gemfile.rails42 +0 -6
@@ -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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
- VERSION = "2.0.0"
4
+ VERSION = '2.7.0'
3
5
  end
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails'
2
4
  require 'enumerize'
3
5
  require 'rspec/matchers/fail_matchers'
@@ -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