statinize 0.2.1 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7814eb5a73fe5fb67c846398c6d22573b183cafd88c243175ef4fb39c5f71fbe
4
- data.tar.gz: b7eec7d141ae6a0deda224802f67dae791ea7b9c96957922c9a7fa9c1b052e6a
3
+ metadata.gz: b3dda46ee65052ce2579b2b223c659c3c76d68d85df008400d14432aeaf53fb1
4
+ data.tar.gz: bd60810a6e386bdad9d9628dc9f1cb2f0cf2b1e04df41f6fc1762109c7909081
5
5
  SHA512:
6
- metadata.gz: 8bea982ae518d67bb7f9c0a9cab47dd081d869dabbdf01874e14de5c2004217bd6f395e5e040f93499cbe5de413e1d3ed6b59222e9d8089cb6b01289748d1be9
7
- data.tar.gz: '08111b888a705bb74fe044f9de93ebcfd6863646df65510bf62e0566b23af1e4ef410609a22b0fc1afb1b15ffac62edbd9b43264a02191504e25296a99eab1e8'
6
+ metadata.gz: d3ca8f71c4efa6b8298fffc4ff94fa45193d7aa0ef60bfb6128ca539683c8500086362e520c6e8937dfd82d7896475d90854b01a947a38519d08105a4c048cb3
7
+ data.tar.gz: d2d6b696b3195cd9b75cfe8b35ce7eb149965ed89c3d79c2f3737e575cb5bcd2a2be80e6e5061c712e4f68a57aa9d71fcdf90a4c5c36a2e7d7f4069d07a2826b
@@ -24,7 +24,7 @@ module Statinize
24
24
  end
25
25
 
26
26
  def should_cast?
27
- key?(:type) && key?(:cast)
27
+ key?(:type) && public_send(:[], :cast)
28
28
  end
29
29
 
30
30
  def should_validate?(instance)
@@ -2,7 +2,8 @@ module Statinize
2
2
  class Attribute
3
3
  include Comparable
4
4
 
5
- attr_reader :klass, :name, :options
5
+ attr_reader :klass, :name
6
+ attr_accessor :options
6
7
 
7
8
  def initialize(klass, name, opts)
8
9
  @klass = klass
@@ -11,7 +12,7 @@ module Statinize
11
12
  @options << opts.clone.extend(Options) unless opts.empty?
12
13
  end
13
14
 
14
- def self.create(klass, name, opts)
15
+ def self.create(klass, name, opts = {})
15
16
  new(klass, name, opts).create
16
17
  end
17
18
 
@@ -9,6 +9,8 @@ module Statinize
9
9
  Symbol => :to_sym,
10
10
  Enumerator => :to_enum,
11
11
  Proc => :to_proc,
12
+ Array => :to_a,
13
+ BigDecimal => :to_d,
12
14
  }.freeze
13
15
 
14
16
  def initialize(instance, attr, option)
@@ -30,7 +32,9 @@ module Statinize
30
32
  attr_reader :instance, :attr_name, :attr_value, :validator_value
31
33
 
32
34
  def castable?
33
- attr_value.respond_to? casting
35
+ return attr_value.respond_to?(casting) if casting.is_a?(String) || casting.is_a?(Symbol)
36
+
37
+ false
34
38
  end
35
39
 
36
40
  def casting
@@ -0,0 +1,60 @@
1
+ # Defines DSL for statinize block
2
+ module Statinize
3
+ module DSL
4
+ def attribute(*attrs, **options)
5
+ attrs.each do |attr|
6
+ Attribute.create(klass, attr, options) unless attribute? attr
7
+ end
8
+ end
9
+
10
+ def validate(*attrs, **options)
11
+ attrs.each do |attr|
12
+ attribute = attributes.find { _1.name == attr }
13
+ attribute = Attribute.create(klass, attr) unless attribute
14
+ attribute.add_options(options)
15
+ end
16
+ end
17
+
18
+ def with(**options, &block)
19
+ instance = self.class.new(klass)
20
+ instance.force(force)
21
+
22
+ klass.instance_variable_set(:@statinizer, instance)
23
+ instance.instance_exec(&block)
24
+ klass.instance_variable_set(:@statinizer, self)
25
+
26
+ instance.merge_options(**options)
27
+
28
+ populate(instance.attributes)
29
+ end
30
+
31
+ def before(&block)
32
+ return unless block_given?
33
+
34
+ before_callbacks << block
35
+ end
36
+
37
+ def force(force = nil)
38
+ force.nil? ? @force : @force = force
39
+ end
40
+
41
+ protected
42
+
43
+ def merge_options(**options)
44
+ attributes.each do |attribute|
45
+ attribute.options.each do |option|
46
+ option.merge!(options)
47
+ end
48
+ end
49
+ end
50
+
51
+ def populate(attrs)
52
+ attrs.each do |attr|
53
+ attribute attr.name
54
+ attributes
55
+ .find { _1.name == attr.name }
56
+ .options = attr.options.clone
57
+ end
58
+ end
59
+ end
60
+ end
@@ -7,10 +7,12 @@ module Statinize
7
7
 
8
8
  class UndefinedAttribute < StandardError; end
9
9
 
10
- class Errors < Array
11
- def to_s
12
- nice_errors = map do |i|
13
- "#{i.keys.first.to_s.split("_").tap { |attr| attr.first.capitalize! }.join(" ")} #{i.values.first}"
10
+ class Errors < Hash
11
+ def nice
12
+ nice_errors = map do |attr_name, errors|
13
+ errors.map do |error|
14
+ "#{attr_name.to_s.split("_").tap { |attr| attr.first.capitalize! }.join(" ")} #{error}"
15
+ end.join("; ")
14
16
  end.join("; ")
15
17
 
16
18
  "ValidationError: #{nice_errors}"
@@ -6,16 +6,21 @@ module Statinize
6
6
  end
7
7
 
8
8
  module PrependedMethods
9
- def initialize(*args, **kwargs, &block)
9
+ def initialize(options = {}, *args, **kwargs, &block)
10
+ symbolized = kwargs.transform_keys(&:to_sym)
11
+ .merge(options.transform_keys(&:to_sym))
12
+
10
13
  if private_methods(false).include? :initialize
11
14
  super(*args, **kwargs, &block)
12
- check_defined!(kwargs)
15
+ check_defined!(symbolized)
13
16
  else
14
17
  statinizer.attributes.map(&:name).each do |attr|
15
- instance_variable_set("@#{attr}", kwargs[attr]) if kwargs.key?(attr)
18
+ instance_variable_set("@#{attr}", symbolized[attr]) if symbolized.key?(attr)
16
19
  end
17
20
  end
18
21
 
22
+ run_before_callbacks
23
+
19
24
  define_validation
20
25
  validate!
21
26
  end
@@ -24,6 +29,10 @@ module Statinize
24
29
  @validation ||= Validation.new(statinizer, self)
25
30
  end
26
31
 
32
+ def run_before_callbacks
33
+ statinizer.run_before_callbacks(self)
34
+ end
35
+
27
36
  def attributes
28
37
  @attributes = Hash[
29
38
  statinizer.attributes.map { |a| [a.name, public_send(a.name)] }
@@ -1,44 +1,19 @@
1
1
  module Statinize
2
2
  class Statinizer
3
- attr_reader :klass
3
+ include DSL
4
4
 
5
- def initialize(klass)
6
- @klass = klass
7
- @force = config.force
8
- end
9
-
10
- def attribute(*attrs, **options)
11
- options.merge!(@with) if @with
12
-
13
- attrs.each do |attr|
14
- Attribute.create(klass, attr, options)
15
- end
16
- end
17
-
18
- def validate(*attrs, **options)
19
- options.merge!(@with) if @with
20
-
21
- attrs.each do |attr|
22
- attribute = attributes.find { _1.name == attr }
23
- attribute&.add_options(options)
24
- end
25
- end
26
-
27
- def with(**kwargs, &block)
28
- @with = kwargs
29
- instance_exec(&block)
30
-
31
- remove_instance_variable(:@with) if @with
32
- end
33
-
34
- def force(force = nil)
35
- force.nil? ? @force : @force = force
36
- end
5
+ attr_reader :klass, :before_callbacks
37
6
 
38
7
  def self.configure(&block)
39
8
  Configuration.configure(&block)
40
9
  end
41
10
 
11
+ def initialize(klass)
12
+ @klass = klass
13
+ @force = config.force
14
+ @before_callbacks = []
15
+ end
16
+
42
17
  def config
43
18
  @config ||= Configuration.instance
44
19
  end
@@ -48,22 +23,28 @@ module Statinize
48
23
  end
49
24
 
50
25
  def add_attribute(attribute)
51
- attributes.add(attribute)
26
+ attributes.add(attribute) unless attribute? attribute
52
27
  end
53
28
 
54
29
  def attributes
55
30
  @attributes ||= Set.new
56
31
  end
57
32
 
33
+ def run_before_callbacks(instance)
34
+ before_callbacks.each do |callback|
35
+ instance.instance_exec(&callback) if callback.is_a? Proc
36
+ end
37
+ end
38
+
58
39
  def attribute?(attribute)
59
- attributes.include? attribute
40
+ attributes.map(&:name).include? attribute.name
60
41
  end
61
42
 
62
43
  def check_validators_exist!
63
44
  raise NoSuchValidatorError unless all_validators_defined?
64
45
  end
65
46
 
66
- private
47
+ protected
67
48
 
68
49
  def all_validators_defined?
69
50
  attributes.map { |attr| attr.options.all_validators_defined? }.all? { !!_1 }
@@ -12,7 +12,7 @@ module Statinize
12
12
  end
13
13
 
14
14
  def validate
15
- @errors = Errors.new
15
+ @errors = Errors.new { |h, k| h[k] = [] }
16
16
  @erroneous_attributes = Hash.new { |h, k| h[k] = Set.new }
17
17
  @erroneous_forced_attributes = Hash.new { |h, k| h[k] = Set.new }
18
18
 
@@ -22,7 +22,7 @@ module Statinize
22
22
  def validate!
23
23
  validate
24
24
 
25
- raise ValidationError, errors.to_s if should_raise?
25
+ raise ValidationError, errors.nice if should_raise?
26
26
  end
27
27
 
28
28
  def valid?
@@ -45,24 +45,38 @@ module Statinize
45
45
  option.validators.each do |validator_class, validator_value|
46
46
  validator_instance = validator_class.new(attr_value, validator_value)
47
47
 
48
+ if option[:type] && option.should_cast? && attr_value.nil? && (option[:presence] || option[:nil] == false)
49
+ cast(attr, option)
50
+ end
51
+
48
52
  next if validator_instance.valid?
49
- next if validator_class == TypeValidator && cast(attr, option)
53
+ next if validator_class == TypeValidator && cast?(attr, option)
50
54
 
51
55
  force = option[:force] ||
52
56
  (statinizer.force? && option[:force].nil?)
53
57
 
54
- erroneous_attributes[attr.name].add option
58
+ erroneous_attributes[attr.name].add? option
59
+
60
+ unless @errors[attr.name].include?(validator_instance.error)
61
+ @errors[attr.name] << validator_instance.error
62
+ end
63
+
55
64
  erroneous_forced_attributes[attr.name].add option if force
56
- @errors << { attr.name => validator_instance.error }
57
65
  end
58
66
  end
59
67
  end
60
68
  end
61
69
 
70
+ def cast?(attr, option)
71
+ option.should_cast? && cast(attr, option)
72
+ end
73
+
62
74
  def cast(attr, option)
63
- caster = Caster.new(instance, attr, option)
75
+ caster(attr, option).cast
76
+ end
64
77
 
65
- option.should_cast? && caster.cast
78
+ def caster(attr, option)
79
+ Caster.new(instance, attr, option)
66
80
  end
67
81
 
68
82
  def should_raise?
@@ -0,0 +1,13 @@
1
+ module Statinize
2
+ class NilValidator < Validator
3
+ def valid?
4
+ return true if validator_value
5
+
6
+ !attr_value.nil?
7
+ end
8
+
9
+ def error
10
+ "is nil"
11
+ end
12
+ end
13
+ end
@@ -1,8 +1,9 @@
1
1
  module Statinize
2
2
  class PresenceValidator < Validator
3
3
  def valid?
4
- validator_value &&
5
- !empty_array? &&
4
+ return true unless validator_value
5
+
6
+ !empty_array? &&
6
7
  !empty_hash? &&
7
8
  !empty_string? &&
8
9
  !attr_value.nil?
@@ -1,7 +1,7 @@
1
1
  module Statinize
2
2
  class TypeValidator < Validator
3
3
  def valid?
4
- attr_value.is_a?(validator_value)
4
+ attr_value.is_a?(validator_value) || attr_value.nil?
5
5
  end
6
6
 
7
7
  def error
data/lib/statinize.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require "set"
2
2
  require "pry"
3
3
  require "singleton"
4
+ require "bigdecimal/util"
4
5
  require_relative "statinize/statinizable"
6
+ require_relative "statinize/dsl"
5
7
  require_relative "statinize/statinizer"
6
8
  require_relative "statinize/configuration"
7
9
  require_relative "statinize/attribute"
@@ -13,5 +15,6 @@ require_relative "statinize/validation"
13
15
  require_relative "statinize/validators/type_validator"
14
16
  require_relative "statinize/validators/presence_validator"
15
17
  require_relative "statinize/validators/inclusion_validator"
18
+ require_relative "statinize/validators/nil_validator"
16
19
  require_relative "statinize/caster"
17
20
  require_relative "statinize/errors"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statinize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Barseek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-08 00:00:00.000000000 Z
11
+ date: 2022-09-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Statinization gem. Allows for creation of attributes for a class with
14
14
  a given type.
@@ -24,12 +24,14 @@ files:
24
24
  - lib/statinize/attribute/options_collection.rb
25
25
  - lib/statinize/caster.rb
26
26
  - lib/statinize/configuration.rb
27
+ - lib/statinize/dsl.rb
27
28
  - lib/statinize/errors.rb
28
29
  - lib/statinize/statinizable.rb
29
30
  - lib/statinize/statinizer.rb
30
31
  - lib/statinize/validation.rb
31
32
  - lib/statinize/validator.rb
32
33
  - lib/statinize/validators/inclusion_validator.rb
34
+ - lib/statinize/validators/nil_validator.rb
33
35
  - lib/statinize/validators/presence_validator.rb
34
36
  - lib/statinize/validators/type_validator.rb
35
37
  homepage: