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
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'i18n'
|
4
|
+
require 'active_support/inflector'
|
5
|
+
|
6
|
+
module Enumerize
|
7
|
+
class Value < String
|
8
|
+
include Predicatable
|
9
|
+
|
10
|
+
attr_reader :value
|
11
|
+
|
12
|
+
def initialize(attr, name, value=nil)
|
13
|
+
if self.class.method_defined?("#{name}?")
|
14
|
+
warn("It's not recommended to use `#{name}` as a field value since `#{name}?` is defined. (#{attr.klass.name}##{attr.name})")
|
15
|
+
end
|
16
|
+
|
17
|
+
@attr = attr
|
18
|
+
@value = value.nil? ? name.to_s : value
|
19
|
+
|
20
|
+
super(name.to_s)
|
21
|
+
|
22
|
+
@i18n_keys = @attr.i18n_scopes.map { |s| :"#{s}.#{self}" }
|
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
|
27
|
+
end
|
28
|
+
|
29
|
+
def text
|
30
|
+
I18n.t(@i18n_keys[0], :default => @i18n_keys[1..-1]) if @i18n_keys
|
31
|
+
end
|
32
|
+
|
33
|
+
def ==(other)
|
34
|
+
super(other.to_s) || value == other
|
35
|
+
end
|
36
|
+
|
37
|
+
def encode_with(coder)
|
38
|
+
coder.represent_object(self.class.superclass, @value)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def predicate_call(value)
|
44
|
+
value == self
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/enumerize.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
require 'active_support/core_ext/object/blank'
|
5
|
+
require 'enumerize/version'
|
6
|
+
|
7
|
+
module Enumerize
|
8
|
+
autoload :Attribute, 'enumerize/attribute'
|
9
|
+
autoload :AttributeMap, 'enumerize/attribute_map'
|
10
|
+
autoload :Value, 'enumerize/value'
|
11
|
+
autoload :Set, 'enumerize/set'
|
12
|
+
autoload :Base, 'enumerize/base'
|
13
|
+
autoload :Module, 'enumerize/module'
|
14
|
+
autoload :Predicates, 'enumerize/predicates'
|
15
|
+
autoload :Predicatable, 'enumerize/predicatable'
|
16
|
+
autoload :Utils, 'enumerize/utils'
|
17
|
+
autoload :ModuleAttributes, 'enumerize/module_attributes'
|
18
|
+
|
19
|
+
autoload :ActiveModelAttributesSupport, 'enumerize/activemodel'
|
20
|
+
autoload :ActiveRecordSupport, 'enumerize/activerecord'
|
21
|
+
autoload :SequelSupport, 'enumerize/sequel'
|
22
|
+
autoload :MongoidSupport, 'enumerize/mongoid'
|
23
|
+
|
24
|
+
module Scope
|
25
|
+
autoload :ActiveRecord, 'enumerize/scope/activerecord'
|
26
|
+
autoload :Sequel, 'enumerize/scope/sequel'
|
27
|
+
autoload :Mongoid, 'enumerize/scope/mongoid'
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.included(base)
|
31
|
+
ActiveSupport::Deprecation.warn '`include Enumerize` was deprecated. Please use `extend Enumerize`.', caller
|
32
|
+
extended(base)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.extended(base)
|
36
|
+
base.send :include, Enumerize::Base
|
37
|
+
base.extend Enumerize::Predicates
|
38
|
+
|
39
|
+
if defined?(::ActiveModel::Attributes)
|
40
|
+
base.extend Enumerize::ActiveModelAttributesSupport
|
41
|
+
end
|
42
|
+
|
43
|
+
if defined?(::ActiveRecord::Base)
|
44
|
+
base.extend Enumerize::ActiveRecordSupport
|
45
|
+
base.extend Enumerize::Scope::ActiveRecord
|
46
|
+
end
|
47
|
+
|
48
|
+
if defined?(::Mongoid::Document)
|
49
|
+
base.extend Enumerize::MongoidSupport
|
50
|
+
base.extend Enumerize::Scope::Mongoid
|
51
|
+
end
|
52
|
+
|
53
|
+
if defined?(::Sequel::Model)
|
54
|
+
base.extend Enumerize::SequelSupport
|
55
|
+
base.extend Enumerize::Scope::Sequel
|
56
|
+
end
|
57
|
+
|
58
|
+
if defined?(::RailsAdmin)
|
59
|
+
require 'enumerize/integrations/rails_admin'
|
60
|
+
base.extend Enumerize::Integrations::RailsAdmin
|
61
|
+
end
|
62
|
+
|
63
|
+
if ::Module === base
|
64
|
+
base.extend Enumerize::Base::ClassMethods
|
65
|
+
base.extend Enumerize::ModuleAttributes
|
66
|
+
end
|
67
|
+
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
begin
|
72
|
+
require 'simple_form'
|
73
|
+
require 'enumerize/hooks/simple_form'
|
74
|
+
require 'enumerize/form_helper'
|
75
|
+
rescue LoadError
|
76
|
+
end
|
77
|
+
|
78
|
+
begin
|
79
|
+
require 'formtastic'
|
80
|
+
require 'enumerize/hooks/formtastic'
|
81
|
+
rescue LoadError
|
82
|
+
end
|
83
|
+
|
84
|
+
begin
|
85
|
+
require 'rspec'
|
86
|
+
rescue LoadError
|
87
|
+
else
|
88
|
+
require 'enumerize/integrations/rspec'
|
89
|
+
end
|
90
|
+
end
|
@@ -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
|
@@ -0,0 +1,261 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
silence_warnings do
|
6
|
+
ActiveRecord::Migration.verbose = false
|
7
|
+
ActiveRecord::Base.logger = Logger.new(nil)
|
8
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveRecord::Base.connection.instance_eval do
|
12
|
+
create_table :users do |t|
|
13
|
+
t.string :sex
|
14
|
+
t.string :role
|
15
|
+
t.string :account_type
|
16
|
+
t.string :status
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class User < ActiveRecord::Base
|
21
|
+
extend Enumerize
|
22
|
+
|
23
|
+
enumerize :sex, :in => [:male, :female], scope: true
|
24
|
+
enumerize :role, :in => [:user, :admin], scope: :having_role
|
25
|
+
enumerize :account_type, :in => [:basic, :premium]
|
26
|
+
enumerize :status, :in => [:active, :disabled], scope: :shallow
|
27
|
+
end
|
28
|
+
|
29
|
+
RSpec.describe Enumerize::Integrations::RSpec::Matcher do
|
30
|
+
|
31
|
+
let(:model) do
|
32
|
+
Class.new do
|
33
|
+
extend Enumerize
|
34
|
+
|
35
|
+
def self.name
|
36
|
+
'Model'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
subject do
|
42
|
+
model.new
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'without qualifier' do
|
46
|
+
it 'accepts when has defined a enumerize' do
|
47
|
+
model.enumerize(:sex, :in => [:male, :female])
|
48
|
+
expect(subject).to enumerize(:sex)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'rejects when has not defined a enumerize' do
|
52
|
+
message = 'Expected Model to define enumerize :sex'
|
53
|
+
expect do
|
54
|
+
expect(subject).to enumerize(:sex)
|
55
|
+
end.to fail_with(message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#in' do
|
60
|
+
context 'defined as array' do
|
61
|
+
before do
|
62
|
+
model.enumerize(:sex, :in => [:male, :female])
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'accepts the right params as an array' do
|
66
|
+
expect(subject).to enumerize(:sex).in([:male, :female])
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'accepts the right params as regular params' do
|
70
|
+
expect(subject).to enumerize(:sex).in(:male, :female)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'accepts the the right params in a different order' do
|
74
|
+
expect(subject).to enumerize(:sex).in(:female, :male)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'rejects wrong params' do
|
78
|
+
message = 'Expected Model to define enumerize :sex in: "boy", "girl"'
|
79
|
+
expect do
|
80
|
+
expect(subject).to enumerize(:sex).in(:boy, :girl)
|
81
|
+
end.to fail_with(message)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'has the right message when negated' do
|
85
|
+
message = 'Did not expect Model to define enumerize :sex in: "female", "male"'
|
86
|
+
expect do
|
87
|
+
expect(subject).to_not enumerize(:sex).in(:male, :female)
|
88
|
+
end.to fail_with(message)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'defined as hash' do
|
93
|
+
before do
|
94
|
+
model.enumerize(:sex, :in => { male: 0, female: 1 })
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'accepts the right params as an array' do
|
98
|
+
expect(subject).to enumerize(:sex).in(:male, :female)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'accepts the right params as a hash' do
|
102
|
+
expect(subject).to enumerize(:sex).in(male: 0, female: 1)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'accepts the right params as a hash in a different order' do
|
106
|
+
expect(subject).to enumerize(:sex).in(female: 1, male: 0)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'rejects wrong keys' do
|
110
|
+
message = 'Expected Model to define enumerize :sex in: "{:boy=>0, :girl=>1}"'
|
111
|
+
expect do
|
112
|
+
expect(subject).to enumerize(:sex).in(boy: 0, girl: 1)
|
113
|
+
end.to fail_with(message)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'rejects wrong values' do
|
117
|
+
message = 'Expected Model to define enumerize :sex in: "{:male=>2, :female=>3}"'
|
118
|
+
expect do
|
119
|
+
expect(subject).to enumerize(:sex).in(male: 2, female: 3)
|
120
|
+
end.to fail_with(message)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'has the right description' do
|
125
|
+
matcher = enumerize(:sex).in(:male, :female)
|
126
|
+
expect(matcher.description).to eq('define enumerize :sex in: "female", "male"')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#with_default' do
|
131
|
+
before do
|
132
|
+
model.enumerize(:sex, :in => [:male, :female], default: :female)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'accepts the right default value' do
|
136
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_default(:female)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'rejects the wrong default value' do
|
140
|
+
message = 'Expected Model to define enumerize :sex in: "female", "male" with "male" as default value'
|
141
|
+
expect do
|
142
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_default(:male)
|
143
|
+
end.to fail_with(message)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'rejects if the `in` is wrong with a correct default value' do
|
147
|
+
message = 'Expected Model to define enumerize :sex in: "boy", "girl" with "female" as default value'
|
148
|
+
expect do
|
149
|
+
expect(subject).to enumerize(:sex).in(:boy, :girl).with_default(:female)
|
150
|
+
end.to fail_with(message)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'has the right description' do
|
154
|
+
matcher = enumerize(:sex).in(:male, :female).with_default(:female)
|
155
|
+
message = 'define enumerize :sex in: "female", "male" with "female" as default value'
|
156
|
+
expect(matcher.description).to eq(message)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe '#with_i18n_scope' do
|
161
|
+
context 'defined as string' do
|
162
|
+
before do
|
163
|
+
model.enumerize(:sex, :in => [:male, :female], i18n_scope: 'sex')
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'accepts the right i18n_scope' do
|
167
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope('sex')
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'rejects the wrong i18n_scope' do
|
171
|
+
message = 'Expected Model to define enumerize :sex in: "female", "male" i18n_scope: "gender"'
|
172
|
+
expect do
|
173
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope('gender')
|
174
|
+
end.to fail_with(message)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'defined as array' do
|
179
|
+
|
180
|
+
before do
|
181
|
+
model.enumerize(:sex, :in => [:male, :female], i18n_scope: ['sex', 'more.sex'])
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'accepts the wrong i18n_scope' do
|
185
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope(['sex', 'more.sex'])
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'rejects the wrong i18n_scope' do
|
189
|
+
message = 'Expected Model to define enumerize :sex in: "female", "male" i18n_scope: ["sex"]'
|
190
|
+
expect do
|
191
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope(['sex'])
|
192
|
+
end.to fail_with(message)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '#with_predicates' do
|
198
|
+
it 'accepts when predicates is defined as a boolean' do
|
199
|
+
model.enumerize(:sex, :in => [:male, :female], predicates: true)
|
200
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(true)
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'accepts when predicates is defined as a hash' do
|
204
|
+
model.enumerize(:sex, :in => [:male, :female], predicates: { prefix: true })
|
205
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(prefix: true)
|
206
|
+
end
|
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
|
+
|
213
|
+
it 'rejects when predicates is not defined' do
|
214
|
+
model.enumerize(:sex, :in => [:male, :female])
|
215
|
+
message = 'Expected Model to define enumerize :sex in: "female", "male" predicates: true'
|
216
|
+
expect do
|
217
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(true)
|
218
|
+
end.to fail_with(message)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe '#with_multiple' do
|
223
|
+
it 'accepts when has defined the multiple' do
|
224
|
+
model.enumerize(:sex, :in => [:male, :female], multiple: true)
|
225
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_multiple(true)
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'rejects when has not defined the multiple' do
|
229
|
+
model.enumerize(:sex, :in => [:male, :female])
|
230
|
+
message = 'Expected Model to define enumerize :sex in: "female", "male" multiple: true'
|
231
|
+
expect do
|
232
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_multiple(true)
|
233
|
+
end.to fail_with(message)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe '#with_scope' do
|
238
|
+
subject do
|
239
|
+
User.new
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'accepts when scope is defined as a boolean' do
|
243
|
+
expect(subject).to enumerize(:sex).in(:male, :female).with_scope(true)
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'accepts when scope is defined as a hash' do
|
247
|
+
expect(subject).to enumerize(:role).in(:user, :admin).with_scope(scope: :having_role)
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'accepts shallow scope' do
|
251
|
+
expect(subject).to enumerize(:status).in(:active, :disabled).with_scope(:shallow)
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'rejects when scope is not defined' do
|
255
|
+
message = 'Expected User to define enumerize :account_type in: "basic", "premium" scope: true'
|
256
|
+
expect do
|
257
|
+
expect(subject).to enumerize(:account_type).in(:basic, :premium).with_scope(true)
|
258
|
+
end.to fail_with(message)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails'
|
4
|
+
require 'enumerize'
|
5
|
+
require 'rspec/matchers/fail_matchers'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.disable_monkey_patching!
|
9
|
+
config.order = :random
|
10
|
+
Kernel.srand config.seed
|
11
|
+
config.filter_run focus: true
|
12
|
+
config.run_all_when_everything_filtered = true
|
13
|
+
|
14
|
+
config.expect_with :rspec do |expectations|
|
15
|
+
expectations.syntax = :expect
|
16
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
17
|
+
end
|
18
|
+
|
19
|
+
config.mock_with :rspec do |mocks|
|
20
|
+
mocks.syntax = :expect
|
21
|
+
mocks.verify_partial_doubles = true
|
22
|
+
end
|
23
|
+
|
24
|
+
if config.files_to_run.one?
|
25
|
+
config.default_formatter = 'doc'
|
26
|
+
end
|
27
|
+
|
28
|
+
config.warnings = true
|
29
|
+
config.include RSpec::Matchers::FailMatchers
|
30
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
if defined?(::ActiveModel::Attributes)
|
6
|
+
|
7
|
+
describe Enumerize do
|
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
|