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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +73 -0
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +210 -0
- data/Gemfile +4 -21
- 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/README.md +366 -73
- data/Rakefile +4 -4
- data/enumerize.gemspec +2 -1
- data/lib/enumerize/activemodel.rb +47 -0
- data/lib/enumerize/activerecord.rb +102 -27
- data/lib/enumerize/attribute.rb +59 -15
- data/lib/enumerize/attribute_map.rb +2 -0
- data/lib/enumerize/base.rb +32 -17
- data/lib/enumerize/hooks/formtastic.rb +7 -9
- data/lib/enumerize/hooks/sequel_dataset.rb +17 -0
- data/lib/enumerize/hooks/simple_form.rb +9 -12
- data/lib/enumerize/hooks/uniqueness.rb +7 -8
- data/lib/enumerize/integrations/rails_admin.rb +3 -1
- data/lib/enumerize/integrations/rspec/matcher.rb +112 -26
- 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 +36 -0
- data/lib/enumerize/predicatable.rb +10 -17
- data/lib/enumerize/predicates.rb +5 -1
- 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 +20 -8
- data/lib/enumerize/utils.rb +12 -0
- data/lib/enumerize/value.rb +20 -20
- data/lib/enumerize/version.rb +3 -1
- data/lib/enumerize.rb +33 -2
- 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 +434 -58
- data/test/attribute_map_test.rb +9 -7
- data/test/attribute_test.rb +52 -23
- data/test/base_test.rb +118 -66
- data/test/formtastic_test.rb +28 -12
- data/test/module_attributes_test.rb +10 -8
- data/test/mongo_mapper_test.rb +26 -11
- data/test/mongoid_test.rb +100 -15
- data/test/multiple_test.rb +41 -12
- data/test/predicates_test.rb +34 -26
- data/test/rails_admin_test.rb +8 -6
- data/test/sequel_test.rb +342 -0
- data/test/set_test.rb +42 -26
- data/test/simple_form_test.rb +25 -1
- data/test/support/mock_controller.rb +6 -0
- data/test/support/shared_enums.rb +43 -0
- data/test/support/view_test_helper.rb +18 -1
- data/test/test_helper.rb +33 -2
- data/test/value_test.rb +79 -28
- metadata +51 -12
- data/.travis.yml +0 -19
- data/Gemfile.rails4 +0 -23
- data/lib/enumerize/form_helper.rb +0 -23
- data/test/rspec_matcher_test.rb +0 -76
- data/test/rspec_spec.rb +0 -13
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
|
@@ -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.
|
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.
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
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.
|
135
|
-
user.
|
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).
|
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.
|
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
|
-
|
295
|
-
|
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
|