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/test/activerecord_test.rb
CHANGED
@@ -1,11 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'active_record'
|
3
5
|
require 'logger'
|
4
6
|
|
7
|
+
db = (ENV['DB'] || 'sqlite3').to_sym
|
8
|
+
|
5
9
|
silence_warnings do
|
6
10
|
ActiveRecord::Migration.verbose = false
|
11
|
+
if ActiveRecord::Base.respond_to?(:use_yaml_unsafe_load)
|
12
|
+
ActiveRecord::Base.use_yaml_unsafe_load = true
|
13
|
+
end
|
7
14
|
ActiveRecord::Base.logger = Logger.new(nil)
|
8
|
-
ActiveRecord::Base.
|
15
|
+
ActiveRecord::Base.configurations = {
|
16
|
+
'sqlite3' => {
|
17
|
+
'adapter' => 'sqlite3',
|
18
|
+
'database' => ':memory:'
|
19
|
+
},
|
20
|
+
'mysql2' => {
|
21
|
+
'adapter' => 'mysql2',
|
22
|
+
'host' => '127.0.0.1',
|
23
|
+
'username' => 'root',
|
24
|
+
'password' => ENV['MYSQL_ROOT_PASSWORD'],
|
25
|
+
'database' => 'enumerize_test',
|
26
|
+
'encoding' => 'utf8mb4',
|
27
|
+
'charset' => 'utf8mb4'
|
28
|
+
},
|
29
|
+
'postgresql' => {
|
30
|
+
'adapter' => 'postgresql',
|
31
|
+
'host' => 'localhost',
|
32
|
+
'username' => ENV['POSTGRES_USER'],
|
33
|
+
'password' => ENV['POSTGRES_PASSWORD']
|
34
|
+
},
|
35
|
+
'postgresql_master' => {
|
36
|
+
'adapter' => 'postgresql',
|
37
|
+
'host' => 'localhost',
|
38
|
+
'username' => ENV['POSTGRES_USER'],
|
39
|
+
'password' => ENV['POSTGRES_PASSWORD'],
|
40
|
+
'database' => 'template1',
|
41
|
+
'schema_search_path' => 'public'
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
case db
|
46
|
+
when :postgresql
|
47
|
+
ActiveRecord::Base.establish_connection(:postgresql_master)
|
48
|
+
ActiveRecord::Base.connection.recreate_database('enumerize_test')
|
49
|
+
when :mysql2
|
50
|
+
if ActiveRecord::Base.configurations.respond_to?(:[])
|
51
|
+
ActiveRecord::Tasks::DatabaseTasks.create ActiveRecord::Base.configurations[db.to_s]
|
52
|
+
else
|
53
|
+
ActiveRecord::Tasks::DatabaseTasks.create ActiveRecord::Base.configurations.find_db_config(db.to_s)
|
54
|
+
end
|
55
|
+
|
56
|
+
ActiveRecord::Base.establish_connection(db)
|
57
|
+
else
|
58
|
+
ActiveRecord::Base.establish_connection(db)
|
59
|
+
end
|
9
60
|
end
|
10
61
|
|
11
62
|
ActiveRecord::Base.connection.instance_eval do
|
@@ -16,11 +67,16 @@ ActiveRecord::Base.connection.instance_eval do
|
|
16
67
|
t.string :name
|
17
68
|
t.string :interests
|
18
69
|
t.integer :status
|
70
|
+
t.text :settings
|
71
|
+
t.integer :skill
|
19
72
|
t.string :account_type, :default => :basic
|
73
|
+
t.string :foo
|
20
74
|
end
|
21
75
|
|
22
76
|
create_table :documents do |t|
|
77
|
+
t.integer :user_id
|
23
78
|
t.string :visibility
|
79
|
+
t.integer :status
|
24
80
|
t.timestamps null: true
|
25
81
|
end
|
26
82
|
end
|
@@ -33,6 +89,9 @@ class BaseEntity < ActiveRecord::Base
|
|
33
89
|
end
|
34
90
|
|
35
91
|
class Document < BaseEntity
|
92
|
+
belongs_to :user
|
93
|
+
|
94
|
+
enumerize :status, in: {draft: 1, release: 2}
|
36
95
|
end
|
37
96
|
|
38
97
|
module RoleEnum
|
@@ -45,18 +104,25 @@ class User < ActiveRecord::Base
|
|
45
104
|
extend Enumerize
|
46
105
|
include RoleEnum
|
47
106
|
|
48
|
-
|
107
|
+
store :settings, accessors: [:language]
|
108
|
+
|
109
|
+
enumerize :sex, :in => [:male, :female], scope: :shallow
|
110
|
+
enumerize :language, :in => [:en, :jp]
|
49
111
|
|
50
112
|
serialize :interests, Array
|
51
113
|
enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true
|
52
114
|
|
53
115
|
enumerize :status, :in => { active: 1, blocked: 2 }, scope: true
|
54
116
|
|
117
|
+
enumerize :skill, :in => { noob: 0, casual: 1, pro: 2 }, scope: :shallow
|
118
|
+
|
55
119
|
enumerize :account_type, :in => [:basic, :premium]
|
56
120
|
|
57
121
|
# There is no column for relationship enumeration for testing purposes: model
|
58
122
|
# should not be broken even if the associated column does not exist yet.
|
59
123
|
enumerize :relationship, :in => [:single, :married]
|
124
|
+
|
125
|
+
has_many :documents
|
60
126
|
end
|
61
127
|
|
62
128
|
class UniqStatusUser < User
|
@@ -68,11 +134,31 @@ class InterestsRequiredUser < User
|
|
68
134
|
validates :interests, presence: true
|
69
135
|
end
|
70
136
|
|
71
|
-
|
137
|
+
class SkipValidationsUser < ActiveRecord::Base
|
138
|
+
self.table_name = "users"
|
139
|
+
include SkipValidationsEnum
|
140
|
+
end
|
141
|
+
|
142
|
+
class DoNotSkipValidationsUser < ActiveRecord::Base
|
143
|
+
self.table_name = "users"
|
144
|
+
include DoNotSkipValidationsEnum
|
145
|
+
end
|
146
|
+
|
147
|
+
class SkipValidationsLambdaUser < ActiveRecord::Base
|
148
|
+
self.table_name = "users"
|
149
|
+
include SkipValidationsLambdaEnum
|
150
|
+
end
|
151
|
+
|
152
|
+
class SkipValidationsLambdaWithParamUser < ActiveRecord::Base
|
153
|
+
self.table_name = "users"
|
154
|
+
include SkipValidationsLambdaWithParamEnum
|
155
|
+
end
|
156
|
+
|
157
|
+
class ActiveRecordTest < MiniTest::Spec
|
72
158
|
it 'sets nil if invalid value is passed' do
|
73
159
|
user = User.new
|
74
160
|
user.sex = :invalid
|
75
|
-
user.sex.
|
161
|
+
expect(user.sex).must_be_nil
|
76
162
|
end
|
77
163
|
|
78
164
|
it 'saves value' do
|
@@ -80,7 +166,7 @@ describe Enumerize::ActiveRecordSupport do
|
|
80
166
|
user = User.new
|
81
167
|
user.sex = :female
|
82
168
|
user.save!
|
83
|
-
user.sex.must_equal 'female'
|
169
|
+
expect(user.sex).must_equal 'female'
|
84
170
|
end
|
85
171
|
|
86
172
|
it 'loads value' do
|
@@ -88,26 +174,43 @@ describe Enumerize::ActiveRecordSupport do
|
|
88
174
|
User.create!(:sex => :male)
|
89
175
|
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
|
90
176
|
user = User.first
|
91
|
-
user.sex.must_equal 'male'
|
92
|
-
user.sex_text.must_equal 'Male'
|
177
|
+
expect(user.sex).must_equal 'male'
|
178
|
+
expect(user.sex_text).must_equal 'Male'
|
93
179
|
end
|
94
180
|
end
|
95
181
|
|
182
|
+
it 'sets nil if invalid stored attribute value is passed' do
|
183
|
+
user = User.new
|
184
|
+
user.language = :invalid
|
185
|
+
expect(user.language).must_be_nil
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'saves stored attribute value' do
|
189
|
+
User.delete_all
|
190
|
+
user = User.new
|
191
|
+
user.language = :en
|
192
|
+
user.save!
|
193
|
+
user.reload
|
194
|
+
expect(user.language).must_equal 'en'
|
195
|
+
end
|
196
|
+
|
96
197
|
it 'has default value' do
|
97
|
-
User.new.role.must_equal 'user'
|
98
|
-
User.new.attributes['role'].must_equal 'user'
|
198
|
+
expect(User.new.role).must_equal 'user'
|
199
|
+
expect(User.new.attributes['role']).must_equal 'user'
|
99
200
|
end
|
100
201
|
|
101
202
|
it 'does not set default value for not selected attributes' do
|
102
203
|
User.delete_all
|
103
204
|
User.create!(:sex => :male)
|
104
205
|
|
105
|
-
|
206
|
+
user = User.select(:id).first
|
207
|
+
expect(user.attributes['role']).must_be_nil
|
208
|
+
expect(user.attributes['lambda_role']).must_be_nil
|
106
209
|
end
|
107
210
|
|
108
211
|
it 'has default value with lambda' do
|
109
|
-
User.new.lambda_role.must_equal 'admin'
|
110
|
-
User.new.attributes['lambda_role'].must_equal 'admin'
|
212
|
+
expect(User.new.lambda_role).must_equal 'admin'
|
213
|
+
expect(User.new.attributes['lambda_role']).must_equal 'admin'
|
111
214
|
end
|
112
215
|
|
113
216
|
it 'uses after_initialize callback to set default value' do
|
@@ -115,11 +218,11 @@ describe Enumerize::ActiveRecordSupport do
|
|
115
218
|
User.create!(sex: 'male', lambda_role: nil)
|
116
219
|
|
117
220
|
user = User.where(:sex => 'male').first
|
118
|
-
user.lambda_role.must_equal 'admin'
|
221
|
+
expect(user.lambda_role).must_equal 'admin'
|
119
222
|
end
|
120
223
|
|
121
224
|
it 'uses default value from db column' do
|
122
|
-
User.new.account_type.must_equal 'basic'
|
225
|
+
expect(User.new.account_type).must_equal 'basic'
|
123
226
|
end
|
124
227
|
|
125
228
|
it 'has default value with default scope' do
|
@@ -127,31 +230,48 @@ describe Enumerize::ActiveRecordSupport do
|
|
127
230
|
default_scope -> { having_role(:user) }
|
128
231
|
end
|
129
232
|
|
130
|
-
UserWithDefaultScope.new.role.must_equal 'user'
|
131
|
-
UserWithDefaultScope.new.attributes['role'].must_equal 'user'
|
233
|
+
expect(UserWithDefaultScope.new.role).must_equal 'user'
|
234
|
+
expect(UserWithDefaultScope.new.attributes['role']).must_equal 'user'
|
132
235
|
end
|
133
236
|
|
134
237
|
it 'validates inclusion' do
|
135
238
|
user = User.new
|
136
239
|
user.role = 'wrong'
|
137
|
-
user.wont_be :valid?
|
138
|
-
user.errors[:role].must_include 'is not included in the list'
|
240
|
+
expect(user).wont_be :valid?
|
241
|
+
expect(user.errors[:role]).must_include 'is not included in the list'
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'sets value to enumerized field from db when record is reloaded' do
|
245
|
+
user = User.create!(interests: [:music])
|
246
|
+
User.find(user.id).update(interests: %i[music dancing])
|
247
|
+
expect(user.interests).must_equal %w[music]
|
248
|
+
user.reload
|
249
|
+
expect(user.interests).must_equal %w[music dancing]
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'has enumerized values in active record attributes after reload' do
|
253
|
+
User.delete_all
|
254
|
+
user = User.new
|
255
|
+
user.status = :blocked
|
256
|
+
user.save!
|
257
|
+
user.reload
|
258
|
+
expect(user.attributes["status"]).must_equal 'blocked'
|
139
259
|
end
|
140
260
|
|
141
261
|
it 'validates inclusion when using write_attribute with string attribute' do
|
142
262
|
user = User.new
|
143
263
|
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'
|
264
|
+
expect(user.read_attribute_for_validation(:role)).must_equal 'wrong'
|
265
|
+
expect(user).wont_be :valid?
|
266
|
+
expect(user.errors[:role]).must_include 'is not included in the list'
|
147
267
|
end
|
148
268
|
|
149
269
|
it 'validates inclusion when using write_attribute with symbol attribute' do
|
150
270
|
user = User.new
|
151
271
|
user.send(:write_attribute, :role, 'wrong')
|
152
|
-
user.read_attribute_for_validation(:role).must_equal 'wrong'
|
153
|
-
user.wont_be :valid?
|
154
|
-
user.errors[:role].must_include 'is not included in the list'
|
272
|
+
expect(user.read_attribute_for_validation(:role)).must_equal 'wrong'
|
273
|
+
expect(user).wont_be :valid?
|
274
|
+
expect(user.errors[:role]).must_include 'is not included in the list'
|
155
275
|
end
|
156
276
|
|
157
277
|
it 'validates inclusion on mass assignment' do
|
@@ -162,47 +282,72 @@ describe Enumerize::ActiveRecordSupport do
|
|
162
282
|
|
163
283
|
it "uses persisted value for validation if it hasn't been set" do
|
164
284
|
user = User.create! :sex => :male
|
165
|
-
User.find(user.id).read_attribute_for_validation(:sex).must_equal 'male'
|
285
|
+
expect(User.find(user.id).read_attribute_for_validation(:sex)).must_equal 'male'
|
166
286
|
end
|
167
287
|
|
168
288
|
it 'is valid with empty string assigned' do
|
169
289
|
user = User.new
|
170
290
|
user.role = ''
|
171
|
-
user.must_be :valid?
|
291
|
+
expect(user).must_be :valid?
|
172
292
|
end
|
173
293
|
|
174
294
|
it 'stores nil when empty string assigned' do
|
175
295
|
user = User.new
|
176
296
|
user.role = ''
|
177
|
-
user.read_attribute(:role).
|
297
|
+
expect(user.read_attribute(:role)).must_be_nil
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'validates inclusion when :skip_validations = false' do
|
301
|
+
user = DoNotSkipValidationsUser.new
|
302
|
+
user.foo = 'wrong'
|
303
|
+
expect(user).wont_be :valid?
|
304
|
+
expect(user.errors[:foo]).must_include 'is not included in the list'
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'does not validate inclusion when :skip_validations = true' do
|
308
|
+
user = SkipValidationsUser.new
|
309
|
+
user.foo = 'wrong'
|
310
|
+
expect(user).must_be :valid?
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'supports :skip_validations option as lambda' do
|
314
|
+
user = SkipValidationsLambdaUser.new
|
315
|
+
user.foo = 'wrong'
|
316
|
+
expect(user).must_be :valid?
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'supports :skip_validations option as lambda with a parameter' do
|
320
|
+
user = SkipValidationsLambdaWithParamUser.new
|
321
|
+
user.foo = 'wrong'
|
322
|
+
expect(user).must_be :valid?
|
178
323
|
end
|
179
324
|
|
180
325
|
it 'supports multiple attributes' do
|
181
326
|
user = User.new
|
182
|
-
user.interests.must_be_empty
|
327
|
+
expect(user.interests).must_be_empty
|
183
328
|
user.interests << :music
|
184
|
-
user.interests.must_equal %w(music)
|
329
|
+
expect(user.interests).must_equal %w(music)
|
185
330
|
user.save!
|
186
331
|
|
187
332
|
user = User.find(user.id)
|
188
|
-
user.interests.must_be_instance_of Enumerize::Set
|
189
|
-
user.interests.must_equal %w(music)
|
333
|
+
expect(user.interests).must_be_instance_of Enumerize::Set
|
334
|
+
expect(user.interests).must_equal %w(music)
|
190
335
|
user.interests << :sports
|
191
|
-
user.interests.must_equal %w(music sports)
|
336
|
+
expect(user.interests).must_equal %w(music sports)
|
192
337
|
|
193
338
|
user.interests = []
|
194
339
|
interests = user.interests
|
195
340
|
interests << :music
|
196
|
-
interests.must_equal %w(music)
|
341
|
+
expect(interests).must_equal %w(music)
|
197
342
|
interests << :dancing
|
198
|
-
interests.must_equal %w(music dancing)
|
343
|
+
expect(interests).must_equal %w(music dancing)
|
199
344
|
end
|
200
345
|
|
201
346
|
it 'stores multiple value passed passed to new' do
|
202
347
|
user = User.new(interests: [:music, :dancing])
|
203
348
|
user.save!
|
204
|
-
user.interests.must_equal %w(music dancing)
|
205
|
-
User.find(user.id).interests.must_equal %w(music dancing)
|
349
|
+
expect(user.interests).must_equal %w(music dancing)
|
350
|
+
expect(User.find(user.id).interests).must_equal %w(music dancing)
|
206
351
|
end
|
207
352
|
|
208
353
|
it 'returns invalid multiple value for validation' do
|
@@ -210,57 +355,66 @@ describe Enumerize::ActiveRecordSupport do
|
|
210
355
|
user.interests << :music
|
211
356
|
user.interests << :invalid
|
212
357
|
values = user.read_attribute_for_validation(:interests)
|
213
|
-
values.must_equal %w(music invalid)
|
358
|
+
expect(values).must_equal %w(music invalid)
|
214
359
|
end
|
215
360
|
|
216
361
|
it 'validates multiple attributes' do
|
217
362
|
user = User.new
|
218
363
|
user.interests << :invalid
|
219
|
-
user.wont_be :valid?
|
364
|
+
expect(user).wont_be :valid?
|
220
365
|
|
221
366
|
user.interests = Object.new
|
222
|
-
user.wont_be :valid?
|
367
|
+
expect(user).wont_be :valid?
|
223
368
|
|
224
369
|
user.interests = ['music', '']
|
225
|
-
user.must_be :valid?
|
370
|
+
expect(user).must_be :valid?
|
226
371
|
end
|
227
372
|
|
228
373
|
it 'stores custom values for multiple attributes' do
|
229
374
|
User.delete_all
|
230
375
|
|
231
|
-
klass = Class.new(User)
|
376
|
+
klass = Class.new(User) do
|
377
|
+
def self.name
|
378
|
+
'UserSubclass'
|
379
|
+
end
|
380
|
+
end
|
232
381
|
klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
|
233
382
|
|
234
383
|
user = klass.new
|
235
384
|
user.interests << :music
|
236
|
-
user.read_attribute(:interests).must_equal [0]
|
237
|
-
user.interests.must_equal %w(music)
|
385
|
+
expect(user.read_attribute(:interests)).must_equal [0]
|
386
|
+
expect(user.interests).must_equal %w(music)
|
238
387
|
user.save
|
239
388
|
|
240
389
|
user = klass.find(user.id)
|
241
|
-
user.interests.must_equal %w(music)
|
390
|
+
expect(user.interests).must_equal %w(music)
|
242
391
|
end
|
243
392
|
|
244
393
|
it 'adds scope' do
|
245
394
|
User.delete_all
|
246
395
|
|
247
|
-
user_1 = User.create!(status: :active, role: :admin)
|
248
|
-
user_2 = User.create!(status: :blocked)
|
396
|
+
user_1 = User.create!(sex: :female, skill: :noob, status: :active, role: :admin)
|
397
|
+
user_2 = User.create!(sex: :female, skill: :casual, status: :blocked)
|
398
|
+
user_3 = User.create!(sex: :male, skill: :pro)
|
399
|
+
|
400
|
+
expect(User.with_status(:active)).must_equal [user_1]
|
401
|
+
expect(User.with_status(:blocked)).must_equal [user_2]
|
402
|
+
expect(User.with_status(:active, :blocked).to_set).must_equal [user_1, user_2].to_set
|
249
403
|
|
250
|
-
User.
|
251
|
-
User.
|
252
|
-
User.with_status(:active, :blocked).to_set.must_equal [user_1, user_2].to_set
|
404
|
+
expect(User.without_status(:active)).must_equal [user_2]
|
405
|
+
expect(User.without_status(:active, :blocked)).must_equal []
|
253
406
|
|
254
|
-
User.
|
255
|
-
User.
|
407
|
+
expect(User.male).must_equal [user_3]
|
408
|
+
expect(User.pro).must_equal [user_3]
|
256
409
|
|
257
|
-
User.
|
410
|
+
expect(User.not_male.to_set).must_equal [user_1, user_2].to_set
|
411
|
+
expect(User.not_pro.to_set).must_equal [user_1, user_2].to_set
|
258
412
|
end
|
259
413
|
|
260
414
|
it 'ignores not enumerized values that passed to the scope method' do
|
261
415
|
User.delete_all
|
262
416
|
|
263
|
-
User.with_status(:foo).must_equal []
|
417
|
+
expect(User.with_status(:foo)).must_equal []
|
264
418
|
end
|
265
419
|
|
266
420
|
it 'allows either key or value as valid' do
|
@@ -268,13 +422,13 @@ describe Enumerize::ActiveRecordSupport do
|
|
268
422
|
user_2 = User.new(status: 1)
|
269
423
|
user_3 = User.new(status: '1')
|
270
424
|
|
271
|
-
user_1.status.must_equal 'active'
|
272
|
-
user_2.status.must_equal 'active'
|
273
|
-
user_3.status.must_equal 'active'
|
425
|
+
expect(user_1.status).must_equal 'active'
|
426
|
+
expect(user_2.status).must_equal 'active'
|
427
|
+
expect(user_3.status).must_equal 'active'
|
274
428
|
|
275
|
-
user_1.must_be :valid?
|
276
|
-
user_2.must_be :valid?
|
277
|
-
user_3.must_be :valid?
|
429
|
+
expect(user_1).must_be :valid?
|
430
|
+
expect(user_2).must_be :valid?
|
431
|
+
expect(user_3).must_be :valid?
|
278
432
|
end
|
279
433
|
|
280
434
|
it 'supports defining enumerized attributes on abstract class' do
|
@@ -282,7 +436,7 @@ describe Enumerize::ActiveRecordSupport do
|
|
282
436
|
|
283
437
|
document = Document.new
|
284
438
|
document.visibility = :protected
|
285
|
-
document.visibility.must_equal 'protected'
|
439
|
+
expect(document.visibility).must_equal 'protected'
|
286
440
|
end
|
287
441
|
|
288
442
|
it 'supports defining enumerized scopes on abstract class' do
|
@@ -291,7 +445,7 @@ describe Enumerize::ActiveRecordSupport do
|
|
291
445
|
document_1 = Document.create!(visibility: :public)
|
292
446
|
document_2 = Document.create!(visibility: :private)
|
293
447
|
|
294
|
-
Document.with_visibility(:public).must_equal [document_1]
|
448
|
+
expect(Document.with_visibility(:public)).must_equal [document_1]
|
295
449
|
end
|
296
450
|
|
297
451
|
it 'validates uniqueness' do
|
@@ -303,7 +457,7 @@ describe Enumerize::ActiveRecordSupport do
|
|
303
457
|
user.status = :active
|
304
458
|
user.valid?
|
305
459
|
|
306
|
-
user.errors[:status].wont_be :empty?
|
460
|
+
expect(user.errors[:status]).wont_be :empty?
|
307
461
|
end
|
308
462
|
|
309
463
|
it 'validates presence with multiple attributes' do
|
@@ -311,17 +465,17 @@ describe Enumerize::ActiveRecordSupport do
|
|
311
465
|
user.interests = []
|
312
466
|
user.valid?
|
313
467
|
|
314
|
-
user.errors[:interests].wont_be :empty?
|
468
|
+
expect(user.errors[:interests]).wont_be :empty?
|
315
469
|
|
316
470
|
user.interests = ['']
|
317
471
|
user.valid?
|
318
472
|
|
319
|
-
user.errors[:interests].wont_be :empty?
|
473
|
+
expect(user.errors[:interests]).wont_be :empty?
|
320
474
|
|
321
475
|
user.interests = [:dancing, :programming]
|
322
476
|
user.valid?
|
323
477
|
|
324
|
-
user.errors[:interests].must_be_empty
|
478
|
+
expect(user.errors[:interests]).must_be_empty
|
325
479
|
end
|
326
480
|
|
327
481
|
it 'is valid after #becomes' do
|
@@ -333,7 +487,7 @@ describe Enumerize::ActiveRecordSupport do
|
|
333
487
|
uniq_user = User.find(user.id).becomes(UniqStatusUser)
|
334
488
|
uniq_user.valid?
|
335
489
|
|
336
|
-
uniq_user.errors.must_be_empty
|
490
|
+
expect(uniq_user.errors).must_be_empty
|
337
491
|
end
|
338
492
|
|
339
493
|
it 'supports multiple attributes in #becomes' do
|
@@ -346,8 +500,8 @@ describe Enumerize::ActiveRecordSupport do
|
|
346
500
|
|
347
501
|
user = uniq_user.becomes(User)
|
348
502
|
|
349
|
-
user.sex.must_equal uniq_user.sex
|
350
|
-
user.interests.must_equal uniq_user.interests
|
503
|
+
expect(user.sex).must_equal uniq_user.sex
|
504
|
+
expect(user.interests).must_equal uniq_user.interests
|
351
505
|
end
|
352
506
|
|
353
507
|
it "doesn't update record" do
|
@@ -369,7 +523,15 @@ describe Enumerize::ActiveRecordSupport do
|
|
369
523
|
user = User.create(:status => :active)
|
370
524
|
user.status = :blocked
|
371
525
|
|
372
|
-
assert_equal [1, 2],
|
526
|
+
assert_equal [1, 2], unsafe_yaml_load(user.changes.to_yaml)[:status]
|
527
|
+
end
|
528
|
+
|
529
|
+
it 'does not change by the practical same value' do
|
530
|
+
user = User.create!(status: 'active')
|
531
|
+
user.reload
|
532
|
+
user.status = 'active'
|
533
|
+
|
534
|
+
expect(user.changes).must_be_empty
|
373
535
|
end
|
374
536
|
|
375
537
|
it 'allows using update_all' do
|
@@ -379,26 +541,30 @@ describe Enumerize::ActiveRecordSupport do
|
|
379
541
|
|
380
542
|
User.update_all(status: :blocked)
|
381
543
|
user.reload
|
382
|
-
user.status.must_equal 'blocked'
|
544
|
+
expect(user.status).must_equal 'blocked'
|
383
545
|
|
384
546
|
User.update_all(status: :active, account_type: :basic)
|
385
547
|
user.reload
|
386
|
-
user.status.must_equal 'active'
|
387
|
-
user.account_type.must_equal 'basic'
|
548
|
+
expect(user.status).must_equal 'active'
|
549
|
+
expect(user.account_type).must_equal 'basic'
|
388
550
|
end
|
389
551
|
|
390
552
|
it 'allows using update_all for multiple enumerize' do
|
391
553
|
User.delete_all
|
392
554
|
|
393
|
-
klass = Class.new(User)
|
555
|
+
klass = Class.new(User) do
|
556
|
+
def self.name
|
557
|
+
'UserSubclass'
|
558
|
+
end
|
559
|
+
end
|
394
560
|
klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
|
395
561
|
|
396
562
|
user = klass.create(status: :active)
|
397
563
|
klass.update_all(status: :blocked, interests: [:music, :dancing])
|
398
564
|
|
399
565
|
user = klass.find(user.id)
|
400
|
-
user.status.must_equal 'blocked'
|
401
|
-
user.interests.must_equal %w(music dancing)
|
566
|
+
expect(user.status).must_equal 'blocked'
|
567
|
+
expect(user.interests).must_equal %w(music dancing)
|
402
568
|
end
|
403
569
|
|
404
570
|
it 'allows using update_all with values' do
|
@@ -408,7 +574,29 @@ describe Enumerize::ActiveRecordSupport do
|
|
408
574
|
|
409
575
|
User.update_all(status: 2)
|
410
576
|
user.reload
|
411
|
-
user.status.must_equal 'blocked'
|
577
|
+
expect(user.status).must_equal 'blocked'
|
578
|
+
end
|
579
|
+
|
580
|
+
it 'allows using update_all on relation objects' do
|
581
|
+
User.delete_all
|
582
|
+
|
583
|
+
user = User.create(status: :active, account_type: :premium)
|
584
|
+
|
585
|
+
User.all.update_all(status: :blocked)
|
586
|
+
user.reload
|
587
|
+
expect(user.status).must_equal 'blocked'
|
588
|
+
end
|
589
|
+
|
590
|
+
it 'allows using update_all on association relation objects' do
|
591
|
+
User.delete_all
|
592
|
+
Document.delete_all
|
593
|
+
|
594
|
+
user = User.create
|
595
|
+
document = Document.create(user: user, status: :draft)
|
596
|
+
|
597
|
+
user.documents.update_all(status: :release)
|
598
|
+
document.reload
|
599
|
+
expect(document.status).must_equal 'release'
|
412
600
|
end
|
413
601
|
|
414
602
|
it 'preserves string usage of update_all' do
|
@@ -418,7 +606,7 @@ describe Enumerize::ActiveRecordSupport do
|
|
418
606
|
|
419
607
|
User.update_all("name = 'Frederick'")
|
420
608
|
user.reload
|
421
|
-
user.name.must_equal 'Frederick'
|
609
|
+
expect(user.name).must_equal 'Frederick'
|
422
610
|
end
|
423
611
|
|
424
612
|
it 'preserves interpolated array usage of update_all' do
|
@@ -428,6 +616,67 @@ describe Enumerize::ActiveRecordSupport do
|
|
428
616
|
|
429
617
|
User.update_all(["name = :name", {name: 'Frederick'}])
|
430
618
|
user.reload
|
431
|
-
user.name.must_equal 'Frederick'
|
619
|
+
expect(user.name).must_equal 'Frederick'
|
620
|
+
end
|
621
|
+
|
622
|
+
it 'sets attribute to nil if given one is not valid' do
|
623
|
+
User.delete_all
|
624
|
+
|
625
|
+
user = User.create(status: :active)
|
626
|
+
|
627
|
+
User.update_all(status: :foo)
|
628
|
+
user.reload
|
629
|
+
expect(user.status).must_be_nil
|
630
|
+
end
|
631
|
+
|
632
|
+
it 'supports AR types serialization' do
|
633
|
+
type = User.type_for_attribute('status')
|
634
|
+
expect(type).must_be_instance_of Enumerize::ActiveRecordSupport::Type
|
635
|
+
serialized = type.serialize('blocked')
|
636
|
+
expect(serialized).must_equal 2
|
637
|
+
end
|
638
|
+
|
639
|
+
it 'has AR type itself JSON serializable' do
|
640
|
+
type = User.type_for_attribute('status')
|
641
|
+
expect(type.as_json['attr']).must_equal 'status'
|
642
|
+
end
|
643
|
+
|
644
|
+
it "doesn't break YAML serialization" do
|
645
|
+
user = unsafe_yaml_load(User.create(status: :blocked).to_yaml)
|
646
|
+
expect(user.status).must_equal 'blocked'
|
647
|
+
end
|
648
|
+
|
649
|
+
# https://github.com/brainspec/enumerize/issues/304
|
650
|
+
it "fallbacks to a raw passed value if AR type can't find value in the attribute" do
|
651
|
+
table = User.arel_table
|
652
|
+
sql = User.where(table[:account_type].matches '%foo%').to_sql
|
653
|
+
|
654
|
+
expect(sql).must_include 'LIKE \'%foo%\''
|
655
|
+
end
|
656
|
+
|
657
|
+
if Rails::VERSION::MAJOR >= 6
|
658
|
+
it 'supports AR#insert_all' do
|
659
|
+
User.delete_all
|
660
|
+
|
661
|
+
User.insert_all([{ sex: :male }])
|
662
|
+
User.insert_all([{ status: :active }])
|
663
|
+
User.insert_all([{ interests: [:music, :sports] }])
|
664
|
+
|
665
|
+
expect(User.exists?(sex: :male)).must_equal true
|
666
|
+
expect(User.exists?(status: :active)).must_equal true
|
667
|
+
expect(User.exists?(interests: [:music, :sports])).must_equal true
|
668
|
+
end
|
669
|
+
|
670
|
+
it 'supports AR#upsert_all' do
|
671
|
+
User.delete_all
|
672
|
+
|
673
|
+
User.upsert_all([{ sex: :male }])
|
674
|
+
User.upsert_all([{ status: :active }])
|
675
|
+
User.upsert_all([{ interests: [:music, :sports] }])
|
676
|
+
|
677
|
+
expect(User.exists?(sex: :male)).must_equal true
|
678
|
+
expect(User.exists?(status: :active)).must_equal true
|
679
|
+
expect(User.exists?(interests: [:music, :sports])).must_equal true
|
680
|
+
end
|
432
681
|
end
|
433
682
|
end
|