enumerize 0.3.0 → 2.3.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 +7 -0
- data/.gitignore +5 -1
- data/.rspec +2 -0
- data/.travis.yml +38 -11
- data/CHANGELOG.md +258 -0
- data/Gemfile +5 -11
- data/Gemfile.global +20 -0
- data/Gemfile.mongo_mapper +7 -0
- data/Gemfile.rails42 +7 -0
- data/Gemfile.rails50 +7 -0
- data/Gemfile.rails52 +7 -0
- data/README.md +405 -17
- data/Rakefile +7 -1
- data/enumerize.gemspec +6 -3
- data/lib/enumerize/activemodel.rb +47 -0
- data/lib/enumerize/activerecord.rb +127 -2
- data/lib/enumerize/attribute.rb +167 -7
- data/lib/enumerize/attribute_map.rb +4 -0
- data/lib/enumerize/base.rb +60 -61
- data/lib/enumerize/hooks/formtastic.rb +11 -12
- data/lib/enumerize/hooks/sequel_dataset.rb +17 -0
- data/lib/enumerize/hooks/simple_form.rb +21 -8
- data/lib/enumerize/hooks/uniqueness.rb +22 -0
- data/lib/enumerize/integrations/rails_admin.rb +18 -0
- data/lib/enumerize/integrations/rspec/matcher.rb +161 -0
- data/lib/enumerize/integrations/rspec.rb +19 -0
- data/lib/enumerize/module.rb +33 -0
- data/lib/enumerize/module_attributes.rb +3 -2
- data/lib/enumerize/mongoid.rb +29 -0
- data/lib/enumerize/predicatable.rb +23 -0
- data/lib/enumerize/predicates.rb +76 -0
- data/lib/enumerize/scope/activerecord.rb +49 -0
- data/lib/enumerize/scope/mongoid.rb +46 -0
- data/lib/enumerize/scope/sequel.rb +52 -0
- data/lib/enumerize/sequel.rb +62 -0
- data/lib/enumerize/set.rb +81 -0
- data/lib/enumerize/utils.rb +12 -0
- data/lib/enumerize/value.rb +19 -46
- data/lib/enumerize/version.rb +3 -1
- data/lib/enumerize.rb +56 -4
- data/lib/sequel/plugins/enumerize.rb +18 -0
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +260 -0
- data/spec/spec_helper.rb +30 -0
- data/test/activemodel_test.rb +114 -0
- data/test/activerecord_test.rb +542 -8
- data/test/attribute_map_test.rb +2 -0
- data/test/attribute_test.rb +102 -4
- data/test/base_test.rb +61 -39
- data/test/formtastic_test.rb +102 -17
- data/test/module_attributes_test.rb +25 -2
- data/test/mongo_mapper_test.rb +84 -0
- data/test/mongoid_test.rb +98 -7
- data/test/multiple_test.rb +59 -0
- data/test/predicates_test.rb +65 -0
- data/test/rails_admin_test.rb +27 -0
- data/test/sequel_test.rb +341 -0
- data/test/set_test.rb +166 -0
- data/test/simple_form_test.rb +110 -4
- data/test/support/mock_controller.rb +11 -1
- data/test/support/shared_enums.rb +43 -0
- data/test/support/view_test_helper.rb +6 -0
- data/test/test_helper.rb +25 -6
- data/test/value_test.rb +102 -13
- metadata +62 -28
- 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.
|
9
|
-
config.
|
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
|
-
|
19
|
+
extend Enumerize
|
17
20
|
|
18
21
|
field :sex
|
19
22
|
field :role
|
20
|
-
|
21
|
-
|
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.
|
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
|
data/test/sequel_test.rb
ADDED
@@ -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
|