File: sequel_test.rb

package info (click to toggle)
ruby-enumerize 2.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 432 kB
  • sloc: ruby: 3,712; makefile: 6
file content (342 lines) | stat: -rw-r--r-- 9,364 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# frozen_string_literal: true

require 'test_helper'
require 'sequel'
require 'logger'
require 'jdbc/sqlite3' if RUBY_PLATFORM == 'java'

class SequelTest < Minitest::Spec
  silence_warnings do
    DB = if RUBY_PLATFORM == 'java'
      Sequel.connect('jdbc:sqlite::memory:')
    else
      Sequel.sqlite
    end
    DB.loggers << Logger.new(nil)
  end

  DB.create_table :users do
    primary_key :id
    String :sex
    String :role
    String :lambda_role
    String :name
    String :interests
    String :status
    Integer :skill
    String :account_type, default: "basic"
    String :foo
  end

  DB.create_table :documents do
    primary_key :id
    String :visibility
    Time :created_at
    Time :updated_at
  end

  class Document < Sequel::Model
    plugin :enumerize
    enumerize :visibility, :in => [:public, :private, :protected], :scope => true, :default => :public
  end

  module RoleEnum
    extend Enumerize
    enumerize :role, :in => [:user, :admin], :default => :user, scope: :having_role
    enumerize :lambda_role, :in => [:user, :admin], :default => lambda { :admin }
  end

  class User < Sequel::Model
    plugin :serialization, :json, :interests
    plugin :dirty
    plugin :defaults_setter
    plugin :validation_helpers
    plugin :enumerize
    include RoleEnum

    enumerize :sex, :in => [:male, :female], scope: :shallow

    enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true

    enumerize :status, :in => { active: 1, blocked: 2 }, scope: true

    enumerize :skill, :in => { noob: 0, casual: 1, pro: 2 }, scope: :shallow

    enumerize :account_type, :in => [:basic, :premium]
  end

  class UniqStatusUser < User
    def validate
      super
      validates_unique :status
      validates_presence :sex
    end
  end

  class SkipValidationsUser < Sequel::Model(:users)
    include SkipValidationsEnum
  end

  class DoNotSkipValidationsUser < Sequel::Model(:users)
    include DoNotSkipValidationsEnum
  end

  class SkipValidationsLambdaUser < Sequel::Model(:users)
    include SkipValidationsLambdaEnum
  end

  class SkipValidationsLambdaWithParamUser < Sequel::Model(:users)
    include SkipValidationsLambdaWithParamEnum
  end

  it 'sets nil if invalid value is passed' do
    user = User.new
    user.sex = :invalid
    expect(user.sex).must_be_nil
  end

  it 'saves value' do
    User.filter{ true }.delete
    user = User.new
    user.sex = :female
    user.save
    expect(user.sex).must_equal 'female'
  end

  it 'loads value' do
    User.filter{ true }.delete
    User.create(:sex => :male)
    store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
      user = User.first
      expect(user.sex).must_equal 'male'
      expect(user.sex_text).must_equal 'Male'
    end
  end

  it 'has default value' do
    expect(User.new.role).must_equal 'user'
    expect(User.new.values[:role]).must_equal 'user'
  end

  it 'does not set default value for not selected attributes' do
    User.filter{ true }.delete
    User.create(:sex => :male)

    assert_equal [:id], User.select(:id).first.values.keys
  end

  it 'has default value with lambda' do
    expect(User.new.lambda_role).must_equal 'admin'
    expect(User.new.values[:lambda_role]).must_equal 'admin'
  end
  it 'uses after_initialize callback to set default value' do
    User.filter{ true }.delete
    User.create(sex: 'male', lambda_role: nil)

    user = User.where(:sex => 'male').first
    expect(user.lambda_role).must_equal 'admin'
  end

  it 'uses default value from db column' do
    expect(User.new.account_type).must_equal 'basic'
  end

  it 'validates inclusion' do
    user = User.new
    user.role = 'wrong'
    expect(user).wont_be :valid?
    expect(user.errors[:role]).must_include 'is not included in the list'
  end

  it 'validates inclusion on mass assignment' do
    assert_raises Sequel::ValidationFailed do
      User.create(role: 'wrong')
    end
  end

  it "uses persisted value for validation if it hasn't been set" do
    user = User.create :sex => :male
    expect(User[user.id].read_attribute_for_validation(:sex)).must_equal 'male'
  end

  it 'is valid with empty string assigned' do
    user = User.new
    user.role = ''
    expect(user).must_be :valid?
  end

  it 'stores nil when empty string assigned' do
    user = User.new
    user.role = ''
    expect(user.values[:role]).must_be_nil
  end

  it 'validates inclusion when :skip_validations = false' do
    user = DoNotSkipValidationsUser.new
    user.foo = 'wrong'
    expect(user).wont_be :valid?
    expect(user.errors[:foo]).must_include 'is not included in the list'
  end

  it 'does not validate inclusion when :skip_validations = true' do
    user = SkipValidationsUser.new
    user.foo = 'wrong'
    expect(user).must_be :valid?
  end

  it 'supports :skip_validations option as lambda' do
    user = SkipValidationsLambdaUser.new
    user.foo = 'wrong'
    expect(user).must_be :valid?
  end

  it 'supports :skip_validations option as lambda with a parameter' do
    user = SkipValidationsLambdaWithParamUser.new
    user.foo = 'wrong'
    expect(user).must_be :valid?
  end

  it 'supports multiple attributes' do
    user = User.new
    user.interests ||= []
    expect(user.interests).must_be_empty
    user.interests << "music"
    expect(user.interests).must_equal %w(music)
    user.save

    user = User[user.id]
    expect(user.interests).must_be_instance_of Enumerize::Set
    expect(user.interests).must_equal %w(music)
    user.interests << "sports"
    expect(user.interests).must_equal %w(music sports)

    user.interests = []
    interests = user.interests
    interests << "music"
    expect(interests).must_equal %w(music)
    interests << "dancing"
    expect(interests).must_equal %w(music dancing)
  end

  it 'returns invalid multiple value for validation' do
    user = User.new
    user.interests << :music
    user.interests << :invalid
    values = user.read_attribute_for_validation(:interests)
    expect(values).must_equal %w(music invalid)
  end

  it 'validates multiple attributes' do
    user = User.new
    user.interests << :invalid
    expect(user).wont_be :valid?

    user.interests = Object.new
    expect(user).wont_be :valid?

    user.interests = ['music', '']
    expect(user).must_be :valid?
  end

  it 'stores custom values for multiple attributes' do
    User.filter{ true }.delete

    klass = Class.new(User)
    klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true

    user = klass.new
    user.interests << :music
    expect(user.interests).must_equal %w(music)
    user.save

    user = klass[user.id]
    expect(user.interests).must_equal %w(music)
  end

  it 'adds scope' do
    User.filter{ true }.delete

    user_1 = User.create(sex: :female, skill: :noob, status: :active, role: :admin)
    user_2 = User.create(sex: :female, skill: :casual, status: :blocked)
    user_3 = User.create(sex: :male, skill: :pro)

    expect(User.with_status(:active).to_a).must_equal [user_1]
    expect(User.with_status(:blocked).to_a).must_equal [user_2]
    expect(User.with_status(:active, :blocked).to_set).must_equal [user_1, user_2].to_set

    expect(User.without_status(:active).to_a).must_equal [user_2]
    expect(User.without_status(:active, :blocked).to_a).must_equal []

    expect(User.having_role(:admin).to_a).must_equal [user_1]
    expect(User.male.to_a).must_equal [user_3]
    expect(User.pro.to_a).must_equal [user_3]

    expect(User.not_male.to_set).must_equal [user_1, user_2].to_set
    expect(User.not_pro.to_set).must_equal [user_1, user_2].to_set
  end

  it 'allows either key or value as valid' do
    user_1 = User.new(status: :active)
    user_2 = User.new(status: 1)
    user_3 = User.new(status: '1')

    expect(user_1.status).must_equal 'active'
    expect(user_2.status).must_equal 'active'
    expect(user_3.status).must_equal 'active'

    expect(user_1).must_be :valid?
    expect(user_2).must_be :valid?
    expect(user_3).must_be :valid?
  end

  it 'supports defining enumerized attributes on abstract class' do
    Document.filter{ true }.delete

    document = Document.new
    document.visibility = :protected
    expect(document.visibility).must_equal 'protected'
  end

  it 'supports defining enumerized scopes on abstract class' do
    Document.filter{ true }.delete

    document_1 = Document.create(visibility: :public)
    document_2 = Document.create(visibility: :private)

    expect(Document.with_visibility(:public).to_a).must_equal [document_1]
  end

  it 'validates uniqueness' do
    user = User.create(status: :active, sex: "male")

    user = UniqStatusUser.new
    user.sex = "male"
    user.status = :active
    expect(user.valid?).must_equal false

    expect(user.errors[:status]).wont_be :empty?
  end

  it "doesn't update record" do
    Document.filter{ true }.delete

    expected = Time.new(2010, 10, 10)

    document = Document.new
    document.updated_at = expected
    document.save

    document = Document.last
    document.save

    assert_equal expected, document.updated_at
  end

  it 'changes from dirty should be serialized as scalar values' do
    user = User.create(:status => :active)
    user.status = :blocked

    expected = { status: [1, 2] }.to_yaml
    assert_equal expected, user.column_changes.to_yaml
  end
end