validated_object 2.0.3 → 2.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
  SHA256:
3
- metadata.gz: 0c1aef88260ebc19d28fa8bd90a400ec6d05c45a60fea1632ebb1b81bbe2b456
4
- data.tar.gz: 239216afd24adc90bb9ae4641253443a91d303e312f49b7bc6f348c541563f5f
3
+ metadata.gz: 66bdc1ee048b6518b260908a2a48e8c4676c4350f99641a0da1c041fdc82a530
4
+ data.tar.gz: 27e9c03469ee86a4875fc9b99d8796055f12e48f7c627bbf410c7b43468c6022
5
5
  SHA512:
6
- metadata.gz: 032c79475b1a99e990f4b04da2cda94cd5cca556cb38e385a783300ef675bfcd2ed51cc055d653b86f77b70270de87518cd7296b1c754a108f11c70d4e989c86
7
- data.tar.gz: affdd5eb1d8dd2525c6b0fd7730fb907317ce0ad3bf8f105b42d67c66aba69e3389c65f7eae85dbfc67ed273e242761a34c67210153f4d9cbaaa694a3e6cac57
6
+ metadata.gz: 667688231472cb2d893ac1235be71c97111831f8f8510164c5152e4d37d4bd99b994c4cb189a36f1feb4af5786d0200b14e74ba27e69b7be3e1929795419d2db
7
+ data.tar.gz: ed1589b44cf7c83d7424ce46b5b09cb1990331aee38bee239232ed2e71b49b32a0c65e2a3fc4ad909c44cd2df1e0b81ee9e65b3191f35621ec50e1be2b499f30
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.2
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.10.6
3
+ - 2.6.6
4
+ - 2.7.1
5
+ before_install: gem install bundler
data/README.md CHANGED
@@ -135,8 +135,7 @@ git commits and tags, and push the `.gem` file to
135
135
 
136
136
  ## Contributing
137
137
 
138
- Bug reports and pull requests are welcome on GitHub at
139
- https://github.com/dogweather/validated_object.
138
+ Bug reports and pull requests are welcome on GitHub.
140
139
 
141
140
 
142
141
  ## License
@@ -1,5 +1,6 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module ValidatedObject
4
- VERSION = '2.0.3'
5
+ VERSION = '2.2.0'
5
6
  end
@@ -1,6 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'active_model'
5
+ require 'sorbet-runtime'
4
6
  require 'validated_object/version'
5
7
 
6
8
  module ValidatedObject
@@ -41,8 +43,11 @@ module ValidatedObject
41
43
  # @see http://www.rubyinside.com/rails-3-0s-activemodel-how-to-give-ruby-classes-some-activerecord-magic-2937.html Rails 3.0′s ActiveModel: How To Give Ruby Classes Some ActiveRecord Magic, Peter Cooper
42
44
  class Base
43
45
  include ActiveModel::Validations
46
+ extend T::Sig
44
47
 
45
- EMPTY_HASH = {}.freeze
48
+ SymbolHash = T.type_alias { T::Hash[Symbol, T.untyped] }
49
+
50
+ EMPTY_HASH = T.let({}.freeze, SymbolHash)
46
51
 
47
52
  # A private class definition, not intended to
48
53
  # be used directly. Implements a pseudo-boolean class
@@ -58,20 +63,21 @@ module ValidatedObject
58
63
  #
59
64
  # @raise [ArgumentError] if the object is not valid at the
60
65
  # end of initialization or `attributes` is not a Hash.
61
- def initialize(attributes=EMPTY_HASH)
62
- raise ArgumentError, "#{attributes} is not a Hash" unless attributes.is_a?(Hash)
63
-
66
+ sig { params(attributes: SymbolHash).void }
67
+ def initialize(attributes = EMPTY_HASH)
64
68
  set_instance_variables from_hash: attributes
65
69
  check_validations!
66
- return self
70
+ nil
67
71
  end
68
72
 
69
73
  # Run any validations and raise an error if invalid.
70
74
  #
71
75
  # @raise [ArgumentError] if any validations fail.
72
76
  # @return [ValidatedObject::Base] the receiver
77
+ sig { returns(ValidatedObject::Base) }
73
78
  def check_validations!
74
79
  raise ArgumentError, errors.full_messages.join('; ') if invalid?
80
+
75
81
  self
76
82
  end
77
83
 
@@ -88,47 +94,70 @@ module ValidatedObject
88
94
  # validates :neutered, type: Boolean, allow_nil: true # Typed but optional
89
95
  # end
90
96
  class TypeValidator < ActiveModel::EachValidator
97
+ extend T::Sig
98
+
91
99
  # @return [nil]
100
+ sig do
101
+ params(
102
+ record: T.untyped,
103
+ attribute: T.untyped,
104
+ value: T.untyped
105
+ )
106
+ .void
107
+ end
92
108
  def validate_each(record, attribute, value)
93
- expected_class = options[:with]
109
+ validation_options = T.let(options, SymbolHash)
110
+
111
+ expected_class = validation_options[:with]
94
112
 
95
113
  return if pseudo_boolean?(expected_class, value) ||
96
114
  expected_class?(expected_class, value)
97
115
 
98
- save_error(record, attribute, value, options)
116
+ save_error(record, attribute, value, validation_options)
99
117
  end
100
118
 
101
-
102
119
  private
103
120
 
121
+ sig { params(expected_class: T.untyped, value: T.untyped).returns(T.untyped) }
104
122
  def pseudo_boolean?(expected_class, value)
105
123
  expected_class == Boolean && boolean?(value)
106
124
  end
107
125
 
126
+ sig { params(expected_class: T.untyped, value: T.untyped).returns(T.untyped) }
108
127
  def expected_class?(expected_class, value)
109
128
  value.is_a?(expected_class)
110
129
  end
111
130
 
131
+ sig { params(value: T.untyped).returns(T.untyped) }
112
132
  def boolean?(value)
113
133
  value.is_a?(TrueClass) || value.is_a?(FalseClass)
114
134
  end
115
135
 
116
- def save_error(record, attribute, value, options)
136
+ sig do
137
+ params(
138
+ record: T.untyped,
139
+ attribute: T.untyped,
140
+ value: T.untyped,
141
+ validation_options: SymbolHash
142
+ )
143
+ .void
144
+ end
145
+ def save_error(record, attribute, value, validation_options)
117
146
  record.errors.add attribute,
118
- options[:message] || "is a #{value.class}, not a #{options[:with]}"
147
+ validation_options[:message] || "is a #{value.class}, not a #{validation_options[:with]}"
119
148
  end
120
149
  end
121
150
 
122
-
123
151
  private
124
152
 
153
+ sig { params(from_hash: SymbolHash).void }
125
154
  def set_instance_variables(from_hash:)
126
155
  from_hash.each do |variable_name, variable_value|
127
156
  # Test for the attribute reader
128
- self.send variable_name.to_sym
157
+ send variable_name.to_sym
129
158
 
130
159
  # Set value in a way that succeeds even if attr is read-only
131
- self.instance_variable_set "@#{variable_name}".to_sym, variable_value
160
+ instance_variable_set "@#{variable_name}".to_sym, variable_value
132
161
  end
133
162
  end
134
163
  end
data/script/demo.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # typed: ignore
1
2
  require 'date'
2
3
  require 'validated_object'
3
4
 
data/sorbet/config ADDED
@@ -0,0 +1,2 @@
1
+ --dir
2
+ .
@@ -0,0 +1,210 @@
1
+ # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2
+ # srb rbi gems
3
+
4
+ # typed: ignore
5
+ #
6
+ # If you would like to make changes to this file, great! Please create the gem's shim here:
7
+ #
8
+ # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/activemodel/all/activemodel.rbi
9
+ #
10
+ # activemodel-6.0.3.2
11
+
12
+ module ActiveModel
13
+ def self.eager_load!; end
14
+ def self.gem_version; end
15
+ def self.version; end
16
+ extend ActiveSupport::Autoload
17
+ end
18
+ module ActiveModel::VERSION
19
+ end
20
+ module ActiveModel::Serializers
21
+ extend ActiveSupport::Autoload
22
+ end
23
+ module ActiveModel::Validations
24
+ def errors; end
25
+ def initialize_dup(other); end
26
+ def invalid?(context = nil); end
27
+ def raise_validation_error; end
28
+ def read_attribute_for_validation(*arg0); end
29
+ def run_validations!; end
30
+ def valid?(context = nil); end
31
+ def validate!(context = nil); end
32
+ def validate(context = nil); end
33
+ def validates_with(*args, &block); end
34
+ extend ActiveSupport::Concern
35
+ end
36
+ module ActiveModel::Validations::ClassMethods
37
+ def _parse_validates_options(options); end
38
+ def _validates_default_keys; end
39
+ def attribute_method?(attribute); end
40
+ def clear_validators!; end
41
+ def inherited(base); end
42
+ def validate(*args, &block); end
43
+ def validates!(*attributes); end
44
+ def validates(*attributes); end
45
+ def validates_each(*attr_names, &block); end
46
+ def validates_with(*args, &block); end
47
+ def validators; end
48
+ def validators_on(*attributes); end
49
+ end
50
+ module ActiveModel::Validations::Clusivity
51
+ def check_validity!; end
52
+ def delimiter; end
53
+ def include?(record, value); end
54
+ def inclusion_method(enumerable); end
55
+ end
56
+ class ActiveModel::Validator
57
+ def initialize(options = nil); end
58
+ def kind; end
59
+ def options; end
60
+ def self.kind; end
61
+ def validate(record); end
62
+ end
63
+ class ActiveModel::EachValidator < ActiveModel::Validator
64
+ def attributes; end
65
+ def check_validity!; end
66
+ def initialize(options); end
67
+ def validate(record); end
68
+ def validate_each(record, attribute, value); end
69
+ end
70
+ class ActiveModel::BlockValidator < ActiveModel::EachValidator
71
+ def initialize(options, &block); end
72
+ def validate_each(record, attribute, value); end
73
+ end
74
+ class ActiveModel::Validations::InclusionValidator < ActiveModel::EachValidator
75
+ def validate_each(record, attribute, value); end
76
+ include ActiveModel::Validations::Clusivity
77
+ end
78
+ module ActiveModel::Validations::HelperMethods
79
+ def _merge_attributes(attr_names); end
80
+ def validates_absence_of(*attr_names); end
81
+ def validates_acceptance_of(*attr_names); end
82
+ def validates_confirmation_of(*attr_names); end
83
+ def validates_exclusion_of(*attr_names); end
84
+ def validates_format_of(*attr_names); end
85
+ def validates_inclusion_of(*attr_names); end
86
+ def validates_length_of(*attr_names); end
87
+ def validates_numericality_of(*attr_names); end
88
+ def validates_presence_of(*attr_names); end
89
+ def validates_size_of(*attr_names); end
90
+ end
91
+ class ActiveModel::Validations::AbsenceValidator < ActiveModel::EachValidator
92
+ def validate_each(record, attr_name, value); end
93
+ end
94
+ class ActiveModel::Validations::NumericalityValidator < ActiveModel::EachValidator
95
+ def allow_only_integer?(record); end
96
+ def check_validity!; end
97
+ def filtered_options(value); end
98
+ def is_hexadecimal_literal?(raw_value); end
99
+ def is_integer?(raw_value); end
100
+ def is_number?(raw_value); end
101
+ def parse_as_number(raw_value); end
102
+ def record_attribute_changed_in_place?(record, attr_name); end
103
+ def validate_each(record, attr_name, value); end
104
+ end
105
+ module ActiveModel::Validations::Callbacks
106
+ def run_validations!; end
107
+ extend ActiveSupport::Concern
108
+ end
109
+ module ActiveModel::Validations::Callbacks::ClassMethods
110
+ def after_validation(*args, &block); end
111
+ def before_validation(*args, &block); end
112
+ end
113
+ class ActiveModel::Validations::ExclusionValidator < ActiveModel::EachValidator
114
+ def validate_each(record, attribute, value); end
115
+ include ActiveModel::Validations::Clusivity
116
+ end
117
+ class ActiveModel::Validations::ConfirmationValidator < ActiveModel::EachValidator
118
+ def confirmation_value_equal?(record, attribute, value, confirmed); end
119
+ def initialize(options); end
120
+ def setup!(klass); end
121
+ def validate_each(record, attribute, value); end
122
+ end
123
+ class ActiveModel::Validations::FormatValidator < ActiveModel::EachValidator
124
+ def check_options_validity(name); end
125
+ def check_validity!; end
126
+ def option_call(record, name); end
127
+ def record_error(record, attribute, name, value); end
128
+ def regexp_using_multiline_anchors?(regexp); end
129
+ def validate_each(record, attribute, value); end
130
+ end
131
+ class ActiveModel::Validations::PresenceValidator < ActiveModel::EachValidator
132
+ def validate_each(record, attr_name, value); end
133
+ end
134
+ class ActiveModel::Validations::LengthValidator < ActiveModel::EachValidator
135
+ def check_validity!; end
136
+ def initialize(options); end
137
+ def skip_nil_check?(key); end
138
+ def validate_each(record, attribute, value); end
139
+ end
140
+ class ActiveModel::Validations::AcceptanceValidator < ActiveModel::EachValidator
141
+ def acceptable_option?(value); end
142
+ def initialize(options); end
143
+ def setup!(klass); end
144
+ def validate_each(record, attribute, value); end
145
+ end
146
+ class ActiveModel::Validations::AcceptanceValidator::LazilyDefineAttributes < Module
147
+ def ==(other); end
148
+ def attributes; end
149
+ def define_on(klass); end
150
+ def included(klass); end
151
+ def initialize(attributes); end
152
+ def matches?(method_name); end
153
+ end
154
+ class ActiveModel::Validations::WithValidator < ActiveModel::EachValidator
155
+ def validate_each(record, attr, val); end
156
+ end
157
+ class ActiveModel::ValidationError < StandardError
158
+ def initialize(model); end
159
+ def model; end
160
+ end
161
+ class ActiveModel::Name
162
+ def !~(**, &&); end
163
+ def <=>(**, &&); end
164
+ def ==(arg); end
165
+ def ===(arg); end
166
+ def =~(**, &&); end
167
+ def _singularize(string); end
168
+ def as_json(**, &&); end
169
+ def cache_key; end
170
+ def collection; end
171
+ def element; end
172
+ def eql?(**, &&); end
173
+ def human(options = nil); end
174
+ def i18n_key; end
175
+ def initialize(klass, namespace = nil, name = nil); end
176
+ def match?(**, &&); end
177
+ def name; end
178
+ def param_key; end
179
+ def plural; end
180
+ def route_key; end
181
+ def singular; end
182
+ def singular_route_key; end
183
+ def to_s(**, &&); end
184
+ def to_str(**, &&); end
185
+ include Comparable
186
+ end
187
+ module ActiveModel::Naming
188
+ def model_name; end
189
+ def self.extended(base); end
190
+ def self.model_name_from_record_or_class(record_or_class); end
191
+ def self.param_key(record_or_class); end
192
+ def self.plural(record_or_class); end
193
+ def self.route_key(record_or_class); end
194
+ def self.singular(record_or_class); end
195
+ def self.singular_route_key(record_or_class); end
196
+ def self.uncountable?(record_or_class); end
197
+ end
198
+ module ActiveModel::Callbacks
199
+ def _define_after_model_callback(klass, callback); end
200
+ def _define_around_model_callback(klass, callback); end
201
+ def _define_before_model_callback(klass, callback); end
202
+ def define_model_callbacks(*callbacks); end
203
+ def self.extended(base); end
204
+ end
205
+ module ActiveModel::Translation
206
+ def human_attribute_name(attribute, options = nil); end
207
+ def i18n_scope; end
208
+ def lookup_ancestors; end
209
+ include ActiveModel::Naming
210
+ end