enumerize 0.8.0 → 2.6.1

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