enumerize 0.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -1
  3. data/.rspec +2 -0
  4. data/.travis.yml +38 -11
  5. data/CHANGELOG.md +258 -0
  6. data/Gemfile +5 -11
  7. data/Gemfile.global +20 -0
  8. data/Gemfile.mongo_mapper +7 -0
  9. data/Gemfile.rails42 +7 -0
  10. data/Gemfile.rails50 +7 -0
  11. data/Gemfile.rails52 +7 -0
  12. data/README.md +405 -17
  13. data/Rakefile +7 -1
  14. data/enumerize.gemspec +6 -3
  15. data/lib/enumerize/activemodel.rb +47 -0
  16. data/lib/enumerize/activerecord.rb +127 -2
  17. data/lib/enumerize/attribute.rb +167 -7
  18. data/lib/enumerize/attribute_map.rb +4 -0
  19. data/lib/enumerize/base.rb +60 -61
  20. data/lib/enumerize/hooks/formtastic.rb +11 -12
  21. data/lib/enumerize/hooks/sequel_dataset.rb +17 -0
  22. data/lib/enumerize/hooks/simple_form.rb +21 -8
  23. data/lib/enumerize/hooks/uniqueness.rb +22 -0
  24. data/lib/enumerize/integrations/rails_admin.rb +18 -0
  25. data/lib/enumerize/integrations/rspec/matcher.rb +161 -0
  26. data/lib/enumerize/integrations/rspec.rb +19 -0
  27. data/lib/enumerize/module.rb +33 -0
  28. data/lib/enumerize/module_attributes.rb +3 -2
  29. data/lib/enumerize/mongoid.rb +29 -0
  30. data/lib/enumerize/predicatable.rb +23 -0
  31. data/lib/enumerize/predicates.rb +76 -0
  32. data/lib/enumerize/scope/activerecord.rb +49 -0
  33. data/lib/enumerize/scope/mongoid.rb +46 -0
  34. data/lib/enumerize/scope/sequel.rb +52 -0
  35. data/lib/enumerize/sequel.rb +62 -0
  36. data/lib/enumerize/set.rb +81 -0
  37. data/lib/enumerize/utils.rb +12 -0
  38. data/lib/enumerize/value.rb +19 -46
  39. data/lib/enumerize/version.rb +3 -1
  40. data/lib/enumerize.rb +56 -4
  41. data/lib/sequel/plugins/enumerize.rb +18 -0
  42. data/spec/enumerize/integrations/rspec/matcher_spec.rb +260 -0
  43. data/spec/spec_helper.rb +30 -0
  44. data/test/activemodel_test.rb +114 -0
  45. data/test/activerecord_test.rb +542 -8
  46. data/test/attribute_map_test.rb +2 -0
  47. data/test/attribute_test.rb +102 -4
  48. data/test/base_test.rb +61 -39
  49. data/test/formtastic_test.rb +102 -17
  50. data/test/module_attributes_test.rb +25 -2
  51. data/test/mongo_mapper_test.rb +84 -0
  52. data/test/mongoid_test.rb +98 -7
  53. data/test/multiple_test.rb +59 -0
  54. data/test/predicates_test.rb +65 -0
  55. data/test/rails_admin_test.rb +27 -0
  56. data/test/sequel_test.rb +341 -0
  57. data/test/set_test.rb +166 -0
  58. data/test/simple_form_test.rb +110 -4
  59. data/test/support/mock_controller.rb +11 -1
  60. data/test/support/shared_enums.rb +43 -0
  61. data/test/support/view_test_helper.rb +6 -0
  62. data/test/test_helper.rb +25 -6
  63. data/test/value_test.rb +102 -13
  64. metadata +62 -28
  65. data/gemfiles/Gemfile-ar-3.1.x +0 -13
data/test/mongoid_test.rb CHANGED
@@ -1,24 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
5
+ begin
6
+
3
7
  silence_warnings do
4
8
  require 'mongoid'
5
9
  end
6
10
 
7
11
  Mongoid.configure do |config|
8
- config.master = Mongo::Connection.new('127.0.0.1', 27017).db('enumerize-test-suite')
9
- config.use_utc = true
10
- config.include_root_in_json = true
12
+ config.connect_to('enumerize-test-suite')
13
+ config.options = { use_utc: true, include_root_in_json: true }
11
14
  end
12
15
 
13
16
  describe Enumerize do
14
17
  class MongoidUser
15
18
  include Mongoid::Document
16
- include Enumerize
19
+ extend Enumerize
17
20
 
18
21
  field :sex
19
22
  field :role
20
- enumerize :sex, :in => %w[male female]
21
- enumerize :role, :in => %w[admine user], :default => 'user'
23
+ field :foo
24
+ field :skill
25
+
26
+ enumerize :sex, :in => %w[male female], scope: true
27
+ enumerize :status, :in => %w[notice warning error], scope: true
28
+ enumerize :role, :in => %w[admin user], :default => 'user', scope: :having_role
29
+ enumerize :mult, :in => %w[one two three four], :multiple => true
30
+ enumerize :foo, :in => %w[bar baz], :skip_validations => true
31
+ enumerize :skill, :in => { noob: 0, casual: 1, pro: 2 }, scope: :shallow
32
+ enumerize :account_type, :in => %w[basic premium], scope: :shallow
22
33
  end
23
34
 
24
35
  before { $VERBOSE = nil }
@@ -29,7 +40,7 @@ describe Enumerize do
29
40
  it 'sets nil if invalid value is passed' do
30
41
  user = model.new
31
42
  user.sex = :invalid
32
- user.sex.must_equal nil
43
+ user.sex.must_be_nil
33
44
  end
34
45
 
35
46
  it 'saves value' do
@@ -54,12 +65,41 @@ describe Enumerize do
54
65
  model.new.role.must_equal 'user'
55
66
  end
56
67
 
68
+ it 'uses after_initialize callback to set default value' do
69
+ model.delete_all
70
+ model.create!(sex: 'male', role: nil)
71
+
72
+ user = model.where(sex: 'male').first
73
+ user.role.must_equal 'user'
74
+ end
75
+
76
+ it 'does not set default value for not selected attributes' do
77
+ model.delete_all
78
+ model.create!(sex: :male)
79
+
80
+ assert_equal ['_id'], model.only(:id).first.attributes.keys
81
+ end
82
+
57
83
  it 'validates inclusion' do
58
84
  user = model.new
59
85
  user.role = 'wrong'
60
86
  user.wont_be :valid?
61
87
  end
62
88
 
89
+ it 'does not validate inclusion when :skip_validations option passed' do
90
+ user = model.new
91
+ user.foo = 'wrong'
92
+ user.must_be :valid?
93
+ end
94
+
95
+ it 'sets value to enumerized field from db when record is reloaded' do
96
+ user = model.create!(mult: [:one])
97
+ model.find(user.id).update(mult: %i[two three])
98
+ user.mult.must_equal %w[one]
99
+ user.reload
100
+ user.mult.must_equal %w[two three]
101
+ end
102
+
63
103
  it 'assigns value on loaded record' do
64
104
  model.delete_all
65
105
  model.create!(:sex => :male)
@@ -67,4 +107,55 @@ describe Enumerize do
67
107
  user.sex = :female
68
108
  user.sex.must_equal 'female'
69
109
  end
110
+
111
+ it 'loads multiple properly' do
112
+ model.delete_all
113
+
114
+ model.create!(:mult => ['one', 'two'])
115
+ user = model.first
116
+ user.mult.to_a.must_equal ['one', 'two']
117
+ end
118
+
119
+ it 'adds scope' do
120
+ model.delete_all
121
+
122
+ user_1 = model.create!(sex: :male, role: :admin)
123
+ user_2 = model.create!(sex: :female, role: :user)
124
+ user_3 = model.create!(skill: :pro, account_type: :premium)
125
+
126
+ model.with_sex(:male).to_a.must_equal [user_1]
127
+ model.with_sex(:female).to_a.must_equal [user_2]
128
+ model.with_sex(:male, :female).to_set.must_equal [user_1, user_2].to_set
129
+
130
+ model.without_sex(:male).to_set.must_equal [user_2, user_3].to_set
131
+ model.without_sex(:female).to_set.must_equal [user_1, user_3].to_set
132
+ model.without_sex(:male, :female).to_a.must_equal [user_3]
133
+
134
+ model.having_role(:admin).to_a.must_equal [user_1]
135
+ model.having_role(:user).to_a.must_equal [user_2, user_3]
136
+
137
+ model.pro.to_a.must_equal [user_3]
138
+ model.premium.to_a.must_equal [user_3]
139
+ end
140
+
141
+ it 'chains scopes' do
142
+ model.delete_all
143
+
144
+ user_1 = model.create!(status: :notice)
145
+ user_2 = model.create!(status: :warning)
146
+ user_3 = model.create!(status: :error)
147
+
148
+ model.with_status(:notice, :warning).with_status(:notice, :error).to_a.must_equal [user_1]
149
+ model.with_status(:notice, :warning).union.with_status(:notice, :error).to_a.must_equal [user_1, user_2, user_3]
150
+ end
151
+
152
+ it 'ignores not enumerized values that passed to the scope method' do
153
+ model.delete_all
154
+
155
+ model.with_sex(:foo).must_equal []
156
+ end
157
+ end
158
+
159
+ rescue LoadError
160
+ # Skip
70
161
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe Enumerize::Base do
6
+ let(:kklass) do
7
+ Class.new do
8
+ extend Enumerize
9
+ end
10
+ end
11
+
12
+ let(:subklass) do
13
+ Class.new(kklass)
14
+ end
15
+
16
+ let(:object) { kklass.new }
17
+
18
+ it 'returns [] when not set' do
19
+ kklass.enumerize :foos, in: %w(a b), multiple: true
20
+ object.foos.must_equal []
21
+ end
22
+
23
+ it 'returns setted array' do
24
+ kklass.enumerize :foos, in: %w(a b c), multiple: true
25
+ object.foos = %w(a c)
26
+ object.foos.must_equal %w(a c)
27
+ end
28
+
29
+ it 'sets default value as single value' do
30
+ kklass.enumerize :foos, in: %w(a b c), default: 'b', multiple: true
31
+ object.foos.must_equal %w(b)
32
+ end
33
+
34
+ it 'sets default value as array of one element' do
35
+ kklass.enumerize :foos, in: %w(a b c), default: %w(b), multiple: true
36
+ object.foos.must_equal %w(b)
37
+ end
38
+
39
+ it 'sets default value as array of several elements' do
40
+ kklass.enumerize :foos, in: %w(a b c), default: %w(b c), multiple: true
41
+ object.foos.must_equal %w(b c)
42
+ end
43
+
44
+ it "doesn't define _text method" do
45
+ kklass.enumerize :foos, in: %w(a b c), multiple: true
46
+ object.wont_respond_to :foos_text
47
+ end
48
+
49
+ it "doesn't define _value method" do
50
+ kklass.enumerize :foos, in: %w(a b c), multiple: true
51
+ object.wont_respond_to :foos_value
52
+ end
53
+
54
+ it "cannot define multiple with scope" do
55
+ assert_raises ArgumentError do
56
+ kklass.enumerize :foos, in: %w(a b c), multiple: true, scope: true
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ describe Enumerize::Predicates do
6
+ let(:kklass) do
7
+ Class.new do
8
+ extend Enumerize
9
+ end
10
+ end
11
+
12
+ let(:object) { kklass.new }
13
+
14
+ it 'creates predicate methods' do
15
+ kklass.enumerize(:foo, in: %w(a b), predicates: true)
16
+ object.must_respond_to :a?
17
+ object.must_respond_to :b?
18
+ end
19
+
20
+ it 'creates predicate methods when enumerized values have dash in it' do
21
+ kklass.enumerize(:foo, in: %w(foo-bar bar-foo), predicates: true)
22
+ object.must_respond_to :foo_bar?
23
+ object.must_respond_to :bar_foo?
24
+ end
25
+
26
+ it 'creates predicate methods on multiple attribute' do
27
+ kklass.enumerize(:foo, in: %w(a b), predicates: true, multiple: true)
28
+ object.must_respond_to :a?
29
+ object.must_respond_to :b?
30
+ end
31
+
32
+ it 'checks values' do
33
+ kklass.enumerize(:foo, in: %w(a b), predicates: true)
34
+ object.foo = 'a'
35
+ object.a?.must_equal true
36
+ object.b?.must_equal false
37
+ end
38
+
39
+ it 'checks values on multiple attribute' do
40
+ kklass.enumerize(:foo, in: %w(a b), predicates: true, multiple: true)
41
+ object.foo << :a
42
+ object.a?.must_equal true
43
+ object.b?.must_equal false
44
+ end
45
+
46
+ it 'prefixes methods' do
47
+ kklass.enumerize(:foo, in: %w(a b), predicates: { prefix: 'bar' })
48
+ object.wont_respond_to :a?
49
+ object.wont_respond_to :b?
50
+ object.must_respond_to :bar_a?
51
+ object.must_respond_to :bar_b?
52
+ end
53
+
54
+ it 'accepts only option' do
55
+ kklass.enumerize(:foo, in: %w(a b), predicates: { only: :a })
56
+ object.must_respond_to :a?
57
+ object.wont_respond_to :b?
58
+ end
59
+
60
+ it 'accepts except option' do
61
+ kklass.enumerize(:foo, in: %w(a b), predicates: { except: :a })
62
+ object.wont_respond_to :a?
63
+ object.must_respond_to :b?
64
+ end
65
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class RailsAdminSpec < MiniTest::Spec
6
+ let(:kklass) do
7
+ Class.new do
8
+ extend Enumerize
9
+ end
10
+ end
11
+
12
+ let(:object) { kklass.new }
13
+
14
+ it 'defines enum method' do
15
+ store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
16
+ kklass.enumerize(:foo, in: [:a, :b])
17
+ object.foo_enum.must_equal [['a text', 'a'], ['b text', 'b']]
18
+ end
19
+ end
20
+
21
+ it 'defines enum properly for custom values enumerations' do
22
+ store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
23
+ kklass.enumerize(:foo, in: {:a => 1, :b => 2})
24
+ object.foo_enum.must_equal [['a text', 'a'], ['b text', 'b']]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,341 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'sequel'
5
+ require 'logger'
6
+ require 'jdbc/sqlite3' if RUBY_PLATFORM == 'java'
7
+
8
+ module SequelTest
9
+ silence_warnings do
10
+ DB = if RUBY_PLATFORM == 'java'
11
+ Sequel.connect('jdbc:sqlite::memory:')
12
+ else
13
+ Sequel.sqlite
14
+ end
15
+ DB.loggers << Logger.new(nil)
16
+ end
17
+
18
+ DB.create_table :users do
19
+ primary_key :id
20
+ String :sex
21
+ String :role
22
+ String :lambda_role
23
+ String :name
24
+ String :interests
25
+ String :status
26
+ Integer :skill
27
+ String :account_type, default: "basic"
28
+ String :foo
29
+ end
30
+
31
+ DB.create_table :documents do
32
+ primary_key :id
33
+ String :visibility
34
+ Time :created_at
35
+ Time :updated_at
36
+ end
37
+
38
+ class Document < Sequel::Model
39
+ plugin :enumerize
40
+ enumerize :visibility, :in => [:public, :private, :protected], :scope => true, :default => :public
41
+ end
42
+
43
+ module RoleEnum
44
+ extend Enumerize
45
+ enumerize :role, :in => [:user, :admin], :default => :user, scope: :having_role
46
+ enumerize :lambda_role, :in => [:user, :admin], :default => lambda { :admin }
47
+ end
48
+
49
+ class User < Sequel::Model
50
+ plugin :serialization, :json, :interests
51
+ plugin :dirty
52
+ plugin :defaults_setter
53
+ plugin :validation_helpers
54
+ plugin :enumerize
55
+ include RoleEnum
56
+
57
+ enumerize :sex, :in => [:male, :female], scope: :shallow
58
+
59
+ enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true
60
+
61
+ enumerize :status, :in => { active: 1, blocked: 2 }, scope: true
62
+
63
+ enumerize :skill, :in => { noob: 0, casual: 1, pro: 2 }, scope: :shallow
64
+
65
+ enumerize :account_type, :in => [:basic, :premium]
66
+ end
67
+
68
+ class UniqStatusUser < User
69
+ def validate
70
+ super
71
+ validates_unique :status
72
+ validates_presence :sex
73
+ end
74
+ end
75
+
76
+ class SkipValidationsUser < Sequel::Model(:users)
77
+ include SkipValidationsEnum
78
+ end
79
+
80
+ class DoNotSkipValidationsUser < Sequel::Model(:users)
81
+ include DoNotSkipValidationsEnum
82
+ end
83
+
84
+ class SkipValidationsLambdaUser < Sequel::Model(:users)
85
+ include SkipValidationsLambdaEnum
86
+ end
87
+
88
+ class SkipValidationsLambdaWithParamUser < Sequel::Model(:users)
89
+ include SkipValidationsLambdaWithParamEnum
90
+ end
91
+
92
+ describe Enumerize::SequelSupport do
93
+ it 'sets nil if invalid value is passed' do
94
+ user = User.new
95
+ user.sex = :invalid
96
+ user.sex.must_be_nil
97
+ end
98
+
99
+ it 'saves value' do
100
+ User.filter{ true }.delete
101
+ user = User.new
102
+ user.sex = :female
103
+ user.save
104
+ user.sex.must_equal 'female'
105
+ end
106
+
107
+ it 'loads value' do
108
+ User.filter{ true }.delete
109
+ User.create(:sex => :male)
110
+ store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
111
+ user = User.first
112
+ user.sex.must_equal 'male'
113
+ user.sex_text.must_equal 'Male'
114
+ end
115
+ end
116
+
117
+ it 'has default value' do
118
+ User.new.role.must_equal 'user'
119
+ User.new.values[:role].must_equal 'user'
120
+ end
121
+
122
+ it 'does not set default value for not selected attributes' do
123
+ User.filter{ true }.delete
124
+ User.create(:sex => :male)
125
+
126
+ assert_equal [:id], User.select(:id).first.values.keys
127
+ end
128
+
129
+ it 'has default value with lambda' do
130
+ User.new.lambda_role.must_equal 'admin'
131
+ User.new.values[:lambda_role].must_equal 'admin'
132
+ end
133
+ it 'uses after_initialize callback to set default value' do
134
+ User.filter{ true }.delete
135
+ User.create(sex: 'male', lambda_role: nil)
136
+
137
+ user = User.where(:sex => 'male').first
138
+ user.lambda_role.must_equal 'admin'
139
+ end
140
+
141
+ it 'uses default value from db column' do
142
+ User.new.account_type.must_equal 'basic'
143
+ end
144
+
145
+ it 'validates inclusion' do
146
+ user = User.new
147
+ user.role = 'wrong'
148
+ user.wont_be :valid?
149
+ user.errors[:role].must_include 'is not included in the list'
150
+ end
151
+
152
+ it 'validates inclusion on mass assignment' do
153
+ assert_raises Sequel::ValidationFailed do
154
+ User.create(role: 'wrong')
155
+ end
156
+ end
157
+
158
+ it "uses persisted value for validation if it hasn't been set" do
159
+ user = User.create :sex => :male
160
+ User[user.id].read_attribute_for_validation(:sex).must_equal 'male'
161
+ end
162
+
163
+ it 'is valid with empty string assigned' do
164
+ user = User.new
165
+ user.role = ''
166
+ user.must_be :valid?
167
+ end
168
+
169
+ it 'stores nil when empty string assigned' do
170
+ user = User.new
171
+ user.role = ''
172
+ user.values[:role].must_be_nil
173
+ end
174
+
175
+ it 'validates inclusion when :skip_validations = false' do
176
+ user = DoNotSkipValidationsUser.new
177
+ user.foo = 'wrong'
178
+ user.wont_be :valid?
179
+ user.errors[:foo].must_include 'is not included in the list'
180
+ end
181
+
182
+ it 'does not validate inclusion when :skip_validations = true' do
183
+ user = SkipValidationsUser.new
184
+ user.foo = 'wrong'
185
+ user.must_be :valid?
186
+ end
187
+
188
+ it 'supports :skip_validations option as lambda' do
189
+ user = SkipValidationsLambdaUser.new
190
+ user.foo = 'wrong'
191
+ user.must_be :valid?
192
+ end
193
+
194
+ it 'supports :skip_validations option as lambda with a parameter' do
195
+ user = SkipValidationsLambdaWithParamUser.new
196
+ user.foo = 'wrong'
197
+ user.must_be :valid?
198
+ end
199
+
200
+ it 'supports multiple attributes' do
201
+ user = User.new
202
+ user.interests ||= []
203
+ user.interests.must_be_empty
204
+ user.interests << "music"
205
+ user.interests.must_equal %w(music)
206
+ user.save
207
+
208
+ user = User[user.id]
209
+ user.interests.must_be_instance_of Enumerize::Set
210
+ user.interests.must_equal %w(music)
211
+ user.interests << "sports"
212
+ user.interests.must_equal %w(music sports)
213
+
214
+ user.interests = []
215
+ interests = user.interests
216
+ interests << "music"
217
+ interests.must_equal %w(music)
218
+ interests << "dancing"
219
+ interests.must_equal %w(music dancing)
220
+ end
221
+
222
+ it 'returns invalid multiple value for validation' do
223
+ user = User.new
224
+ user.interests << :music
225
+ user.interests << :invalid
226
+ values = user.read_attribute_for_validation(:interests)
227
+ values.must_equal %w(music invalid)
228
+ end
229
+
230
+ it 'validates multiple attributes' do
231
+ user = User.new
232
+ user.interests << :invalid
233
+ user.wont_be :valid?
234
+
235
+ user.interests = Object.new
236
+ user.wont_be :valid?
237
+
238
+ user.interests = ['music', '']
239
+ user.must_be :valid?
240
+ end
241
+
242
+ it 'stores custom values for multiple attributes' do
243
+ User.filter{ true }.delete
244
+
245
+ klass = Class.new(User)
246
+ klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
247
+
248
+ user = klass.new
249
+ user.interests << :music
250
+ user.interests.must_equal %w(music)
251
+ user.save
252
+
253
+ user = klass[user.id]
254
+ user.interests.must_equal %w(music)
255
+ end
256
+
257
+ it 'adds scope' do
258
+ User.filter{ true }.delete
259
+
260
+ user_1 = User.create(status: :active, role: :admin)
261
+ user_2 = User.create(status: :blocked)
262
+ user_3 = User.create(sex: :male, skill: :pro)
263
+
264
+ User.with_status(:active).to_a.must_equal [user_1]
265
+ User.with_status(:blocked).to_a.must_equal [user_2]
266
+ User.with_status(:active, :blocked).to_set.must_equal [user_1, user_2].to_set
267
+
268
+ User.without_status(:active).to_a.must_equal [user_2]
269
+ User.without_status(:active, :blocked).to_a.must_equal []
270
+
271
+ User.having_role(:admin).to_a.must_equal [user_1]
272
+ User.male.to_a.must_equal [user_3]
273
+ User.pro.to_a.must_equal [user_3]
274
+ end
275
+
276
+ it 'allows either key or value as valid' do
277
+ user_1 = User.new(status: :active)
278
+ user_2 = User.new(status: 1)
279
+ user_3 = User.new(status: '1')
280
+
281
+ user_1.status.must_equal 'active'
282
+ user_2.status.must_equal 'active'
283
+ user_3.status.must_equal 'active'
284
+
285
+ user_1.must_be :valid?
286
+ user_2.must_be :valid?
287
+ user_3.must_be :valid?
288
+ end
289
+
290
+ it 'supports defining enumerized attributes on abstract class' do
291
+ Document.filter{ true }.delete
292
+
293
+ document = Document.new
294
+ document.visibility = :protected
295
+ document.visibility.must_equal 'protected'
296
+ end
297
+
298
+ it 'supports defining enumerized scopes on abstract class' do
299
+ Document.filter{ true }.delete
300
+
301
+ document_1 = Document.create(visibility: :public)
302
+ document_2 = Document.create(visibility: :private)
303
+
304
+ Document.with_visibility(:public).to_a.must_equal [document_1]
305
+ end
306
+
307
+ it 'validates uniqueness' do
308
+ user = User.create(status: :active, sex: "male")
309
+
310
+ user = UniqStatusUser.new
311
+ user.sex = "male"
312
+ user.status = :active
313
+ user.valid?.must_equal false
314
+
315
+ user.errors[:status].wont_be :empty?
316
+ end
317
+
318
+ it "doesn't update record" do
319
+ Document.filter{ true }.delete
320
+
321
+ expected = Time.new(2010, 10, 10)
322
+
323
+ document = Document.new
324
+ document.updated_at = expected
325
+ document.save
326
+
327
+ document = Document.last
328
+ document.save
329
+
330
+ assert_equal expected, document.updated_at
331
+ end
332
+
333
+ it 'changes from dirty should be serialized as scalar values' do
334
+ user = User.create(:status => :active)
335
+ user.status = :blocked
336
+
337
+ expected = { status: [1, 2] }.to_yaml
338
+ assert_equal expected, user.column_changes.to_yaml
339
+ end
340
+ end
341
+ end