validates_type 1.1.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8e375accce8736d3c0507854a2376f120bef33ad
4
- data.tar.gz: c87bdb0cc929a00367e84107f4179fb966ea3e8e
3
+ metadata.gz: 4eaad53649c687b0db1d873919a5e0d3977abfc1
4
+ data.tar.gz: 216e38fc24aed68917f29979875fc0518bbaa5f2
5
5
  SHA512:
6
- metadata.gz: 1ead0fd0a56040f24f0cd22fb00aef94a2a147d69b7d36aa72bff418a2c277c893bff23bf31a42277ca131aecbb7eaebc9fd2dfc11cddb42904fc9ad80ceb12a
7
- data.tar.gz: ff938b6e88cf84482e361fa5c658ce1c11c662a56051d25856531e3bf391594aa473387323f6a3d846f5730ec5d0970ecdc42d46e4a640ea768903f1ea802b21
6
+ metadata.gz: 0d3d79da0e73d4a8a37abb36ea65c5e936e862a655faf280a95233d50f5f61759c6214cd8d935214b62fe4ab334cc548ba5db878a47381c73a8a12f477f002e0
7
+ data.tar.gz: 517ec6573c60bfe54372fec7c9f9681ec9735b63eb5955ad6df79510d7fbdceba22a96a21a0e781a64a031cc5f3f6efeaa43a47d01eb2bbb2345d7a8073115dc
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  .ruby*
2
2
  *.gem
3
+ .bundle
4
+ .idea
data/README.md CHANGED
@@ -37,6 +37,9 @@ class Foo < ActiveRecord::Base
37
37
 
38
38
  # validate that attribute :birthday is a Date or blank
39
39
  validates_type :birthday, :date, allow_blank: true
40
+
41
+ # validate that attribute :fox is of type Custom
42
+ validates_type :fox, Custom
40
43
  end
41
44
  ```
42
45
 
@@ -98,4 +101,4 @@ end
98
101
  - `:symbol`
99
102
  - `:time`
100
103
 
101
-
104
+ #### Any class name, possibly something custom defined in your app, is also game.
@@ -16,7 +16,7 @@ module ActiveModel
16
16
  # return: result of ActiveModel::Validations::EachValidator initialize
17
17
  def initialize(options)
18
18
  merged_options = {
19
- :message => "is expected to be a #{ symbol_class(options[:type]) } and is not."
19
+ :message => "is expected to be a #{ type_class(options[:type]) } and is not."
20
20
  }.merge(options)
21
21
 
22
22
  super(merged_options)
@@ -31,7 +31,7 @@ module ActiveModel
31
31
  # return: nil
32
32
  def validate_each(record, attribute, value)
33
33
  value_to_test = type_before_coercion(record, attribute, value)
34
- expected_type = symbol_class(options[:type])
34
+ expected_type = type_class(options[:type])
35
35
 
36
36
  add_errors_or_raise(options, record, attribute) unless value_to_test.is_a?(expected_type)
37
37
  end
@@ -71,6 +71,21 @@ module ActiveModel
71
71
  end
72
72
  end
73
73
 
74
+ # Helper method to get back a class constant from the given type option
75
+ # If the type option is a class, it will be returned as is.
76
+ # If it is not a class, the method will try to convert it to a class constant.
77
+ #
78
+ # ex:
79
+ # type_class(:string) -> String
80
+ # type_class(String) -> String
81
+ # type_class(Custom) -> Custom
82
+ # @type_class
83
+ # param: type <Class, Symbol>
84
+ # return: <Class> class constant
85
+ def type_class(type)
86
+ @type_class ||= type.is_a?(Class) ? type : symbol_class(type)
87
+ end
88
+
74
89
  # Helper method to convert a symbol into a class constant
75
90
  #
76
91
  # ex:
@@ -79,10 +94,10 @@ module ActiveModel
79
94
  # symbol_class(:hash) -> Hash
80
95
  #
81
96
  # @symbol_class
82
- # param: symbol <Symbol> - symbol to turn into a classconstant
97
+ # param: symbol <Symbol> - symbol to turn into a class constant
83
98
  # return: class constant of supported types or raises UnsupportedType
84
99
  def symbol_class(symbol)
85
- @symbol_class ||= {
100
+ {
86
101
  :array => Array,
87
102
  :boolean => Boolean,
88
103
  :float => Float,
@@ -122,20 +137,23 @@ module ActiveModel
122
137
  # - :date
123
138
  # - :big_decimal
124
139
  #
140
+ # Also validates the type of an attribute given a custom type class constant.
141
+ #
125
142
  # class Foo
126
143
  # include ActiveModel::Validations
127
144
  #
128
- # attr_accessor :thing, :something
145
+ # attr_accessor :thing, :something, :custom_thing
129
146
  #
130
147
  # validates_type :thing, :boolean
131
148
  # validates_type :something, :array
149
+ # validates_type :custom_thing, Custom
132
150
  # end
133
151
  #
134
152
  # @validates_type
135
153
  # param: attribute_name <Symbol> - name of attribute to validate
136
- # param: attribute_type <Symbol> - type of attribute to validate against
137
- # param: options <Hash> - other common options to validate methods calls
138
- # i.e. message: 'my custom error message'
154
+ # param: attribute_type <Symbol, Class> - type of attribute to validate against
155
+ # param: options <Hash> - other common options to validate methods calls
156
+ # i.e. message: 'my custom error message'
139
157
  # return: nil
140
158
  def validates_type(attribute_name, attribute_type, options = {})
141
159
  args = ValidatesType::Arguments.new(attribute_name, attribute_type, options)
@@ -292,4 +292,35 @@ describe 'ValidatesType' do
292
292
  end
293
293
  end
294
294
  end
295
+
296
+ context 'custom class' do
297
+ class Custom; end
298
+ subject { ActiveModel::TypeValidationTestClass.set_accessor_and_long_validator(Custom) }
299
+
300
+ before do
301
+ subject.attribute = value
302
+ end
303
+
304
+ context 'field value is of type Custom' do
305
+ let(:value) { Custom.new }
306
+
307
+ specify do
308
+ expect(subject).to be_valid
309
+ end
310
+ end
311
+
312
+ context 'field value is not of type Custom' do
313
+ let(:value) { -1 }
314
+
315
+ specify do
316
+ expect(subject).to_not be_valid
317
+ end
318
+
319
+ specify do
320
+ subject.validate
321
+ expect(subject.errors).to_not be_empty
322
+ expect(subject.errors.messages[:attribute][0]).to match(/is expected to be a Custom and is not/)
323
+ end
324
+ end
325
+ end
295
326
  end
@@ -12,14 +12,14 @@ module ActiveModel
12
12
  # end
13
13
  #
14
14
  # @set_accessor_and_long_validator
15
- # param: type <Symbol> - type which to validate against
15
+ # param: type <Symbol, Class> - type which to validate against
16
16
  # param: options<Hash *Optional*> - extra modifiers/custom messaging
17
17
  # return: TypeValidationTestClass instance with set validator
18
18
  def self.set_accessor_and_long_validator(type, options = {})
19
19
  self.new.tap do |test_class|
20
20
  test_class._validators = {}
21
21
  test_class.class_eval { attr_accessor :attribute }
22
- test_class.class_eval { validates_type :attribute, type.to_sym, options }
22
+ test_class.class_eval { validates_type :attribute, type, options }
23
23
  end
24
24
  end
25
25
 
@@ -33,7 +33,7 @@ module ActiveModel
33
33
  # end
34
34
  #
35
35
  # @set_accessor_and_long_validator
36
- # param: type <Symbol> - type which to validate against
36
+ # param: type <Symbol, Class> - type which to validate against
37
37
  # param: options<Hash *Optional*> - extra modifiers/custom messaging
38
38
  # return: TypeValidationTestClass instance with set validator
39
39
  def self.set_accessor_and_validator(type, options = {})
@@ -20,7 +20,7 @@ class TypeValidationTest < ActiveRecord::Base
20
20
  def self.set_accessor_and_long_validator(type, options = {})
21
21
  self.new.tap do |test_class|
22
22
  test_class._validators = {}
23
- test_class.class_eval { validates_type :test_attribute, type.to_sym, options }
23
+ test_class.class_eval { validates_type :test_attribute, type, options }
24
24
  end
25
25
  end
26
26
 
@@ -385,4 +385,49 @@ describe 'ValidatesType' do
385
385
  end
386
386
  end
387
387
  end
388
+
389
+ context 'custom class' do
390
+ drop_and_create_column_with_type(:string)
391
+ class Custom; end
392
+ subject { TypeValidationTest.set_accessor_and_long_validator(Custom) }
393
+
394
+ before do
395
+ subject.test_attribute = value
396
+ end
397
+
398
+ context 'field value is of type Custom' do
399
+ let(:value) { Custom.new }
400
+
401
+ specify do
402
+ expect(subject).to be_valid
403
+ end
404
+ end
405
+
406
+ context 'field value is not of type Custom' do
407
+ let(:value) { -1 }
408
+
409
+ specify do
410
+ expect(subject).to_not be_valid
411
+ end
412
+
413
+ specify do
414
+ subject.validate
415
+ expect(subject.errors).to_not be_empty
416
+ expect(subject.errors.messages[:test_attribute][0]).to match(/is expected to be a Custom and is not/)
417
+ end
418
+ end
419
+
420
+ context 'passing in a custom message' do
421
+ subject { TypeValidationTest.set_accessor_and_long_validator(Custom, message: 'is not Custom!') }
422
+
423
+ context 'when validation fails' do
424
+ let(:value) { 1 }
425
+
426
+ specify do
427
+ subject.validate
428
+ expect(subject.errors.messages[:test_attribute][0]).to match(/is not Custom!/)
429
+ end
430
+ end
431
+ end
432
+ end
388
433
  end
data/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ValidatesType
2
- VERSION = '1.1.0'.freeze
2
+ VERSION = '1.2.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validates_type
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Yesbeck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-16 00:00:00.000000000 Z
11
+ date: 2015-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-boolean