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