hashy_validator 0.1.3 → 0.1.5

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: 169c5f3bf1fa5deb20aaa9788eb1dc2bef55031a026b6b2d67ee050749edd9a1
4
- data.tar.gz: 9a583d90637b4aec761dc5dfe6a133e34c8b62cd11b53d653567e632e0a096f6
3
+ metadata.gz: 65bbe593f0a313de084f7bd4a7ab23075422a068a7bea5dc6903f55a7243b09e
4
+ data.tar.gz: b86b243a6e39958a38b8c51bd1d2ce2644e0581a6929956faf74d8c83cab2a34
5
5
  SHA512:
6
- metadata.gz: f8853fec7ff9a3f67432d8ec71e68faf680f964317c6a874a12711a237faa1eeb8e7e55a4eda73c3570eb406975481529efaf9a1a8fea9d2867233f16842f1d2
7
- data.tar.gz: a9c9f21c28c9036a943a6599173ac2a524b1ae70ac66dea91c979fe9f923330d58ab3d554e24e67ea3175ce0b9ce1effeba2e366c3616c9e08b0fa6a1be02756
6
+ metadata.gz: af7fd7055e2bf2462ae5784668f7c42d502abfd293e72c4ded6d17d5694182b92342ffb3f22a45063534d81ad53b15c0652092e66490abe46a8428a8acfba166
7
+ data.tar.gz: 74a8d08f9409cd379a2be4af5a82118323ed36dbfb097cddac2fc9b8860348efb37d401c18da6040dbd04bc70adde05483dd72d600fc716d1c58af1d5c7fbd2b
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ### [0.1.5](https://www.github.com/flecto-io/hashy-validator/compare/v0.1.4...v0.1.5) (2024-09-05)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * add hashy_object ([35e1ccf](https://www.github.com/flecto-io/hashy-validator/commit/35e1ccf1cff9d95df069961c8ac1b3fec6d23645))
14
+
8
15
  ### [0.1.4](https://www.github.com/flecto-io/hashy-validator/compare/v0.1.3...v0.1.4) (2024-08-24)
9
16
 
10
17
 
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency 'simplecov', '0.17.1'
23
23
  spec.add_development_dependency 'rubocop', '~> 1.59'
24
24
  spec.add_development_dependency 'rubocop-shopify', '~> 2.14'
25
+ spec.add_development_dependency 'pry', '~> 0.14.1'
25
26
 
26
27
  if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3")
27
28
  spec.add_development_dependency 'minitest', '>= 5.15.0', '< 5.16'
@@ -2,65 +2,42 @@
2
2
 
3
3
  class HashyArrayValidator < ActiveModel::EachValidator
4
4
  def validate_each(record, attribute, value)
5
- instance_value = HashyValueValidator.new(value)
5
+ instance_value = HashyValueValidator.new(value, options)
6
+
6
7
  unless instance_value.valid?
7
8
  record.errors.add(attribute, instance_value.reason)
8
9
  return false
9
10
  end
10
11
 
11
- value = instance_value.value
12
+ unless instance_value.value.is_a?(Array)
13
+ record.errors.add(attribute, :not_an_array)
14
+ return false
15
+ end
12
16
 
13
- # look for boolean and unique validator entries
14
- unique_attrs = {}
15
- boolean_attrs = []
16
- validations =
17
- # force validator keys to be strings
18
- options.stringify_keys.map do |val_attr, val|
19
- is_multiple = val.is_a?(HashValidator::Validations::Multiple)
20
- if (is_multiple && val.validations.include?("boolean")) || (val.is_a?(String) && val == "boolean")
21
- boolean_attrs << val_attr
22
- [val_attr, val]
23
- elsif is_multiple && val.validations.include?("unique")
24
- # if unique key present, then remove that entry
25
- # (since its not from HashValidator standard) and keep its history
26
- unique_attrs[val_attr] ||= []
27
- # we have to make a new object to remove the unique entry,
28
- # because deleting it directly from the original object
29
- # (val) would result into deleting the verification forever
30
- new_val = HashValidator::Validations::Multiple.new(val.validations.reject { |v| v == "unique" })
31
- # return the value
32
- val.validations.blank? ? nil : [val_attr, new_val]
33
- elsif val.is_a?(String) && val == "unique"
34
- # same as above but substring
35
- unique_attrs[val_attr] ||= []
36
- nil
37
- else
38
- [val_attr, val]
39
- end
40
- end.compact.to_h
17
+ value = instance_value.value
41
18
 
42
19
  # force all array entries to have string keys
43
20
  # discard keys that do not have validators
44
- value = value.map { |e| e.stringify_keys.slice(*validations.keys) }
21
+ value = value.map { |e| e.stringify_keys.slice(*instance_value.validations.keys) }
45
22
 
46
23
  # we validate each object in the array
47
24
  value.each do |t|
48
25
  # if boolean found as any of the validations we force value to boolean - if present
49
- boolean_attrs.each do |boolean_attr|
50
- t[boolean_attr] = get_boolean_value(t[boolean_attr]) if t.key?(boolean_attr)
26
+ instance_value.boolean_attrs.each do |boolean_attr|
27
+ t[boolean_attr] = HashyValueValidator.get_boolean_value(t[boolean_attr]) if t.key?(boolean_attr)
51
28
  end
52
29
 
53
30
  # keep track of unique values and add error if needed
54
- unique_attrs.each_key do |unique_attr|
55
- if unique_attrs[unique_attr].include?(t[unique_attr])
31
+ instance_value.unique_attrs.each_key do |unique_attr|
32
+ if instance_value.unique_attrs[unique_attr].include?(t[unique_attr])
56
33
  record.errors.add(attribute, "'#{unique_attr}' not unique")
57
34
  else
58
- unique_attrs[unique_attr] << t[unique_attr]
35
+ instance_value.unique_attrs[unique_attr] << t[unique_attr]
59
36
  end
60
37
  end
61
38
 
62
39
  # use default hash validator
63
- validator = HashValidator.validate(t, validations)
40
+ validator = HashValidator.validate(t, instance_value.validations)
64
41
  unless validator.valid?
65
42
  validator.errors.each { |k, v| record.errors.add(attribute, "'#{k}' #{v}") }
66
43
  end
@@ -70,13 +47,4 @@ class HashyArrayValidator < ActiveModel::EachValidator
70
47
  # we use send write param so we also support attr_accessor attributes
71
48
  record.send("#{attribute}=", value)
72
49
  end
73
-
74
- private
75
-
76
- def get_boolean_value(value)
77
- return true if [true, "true"].include?(value)
78
- return false if [false, "false"].include?(value)
79
-
80
- nil
81
- end
82
50
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ class HashyObjectValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, value)
5
+ instance_value = HashyValueValidator.new(value, options)
6
+
7
+ # Do not validate empty hash
8
+ return if instance_value.value.keys.empty?
9
+
10
+ unless instance_value.valid?
11
+ record.errors.add(attribute, instance_value.reason)
12
+ return false
13
+ end
14
+
15
+ if instance_value.value.is_a?(Array)
16
+ record.errors.add(attribute, :not_an_object)
17
+ return false
18
+ end
19
+
20
+ # force all array entries to have string keys
21
+ # discard keys that do not have validators
22
+ value = instance_value.value.stringify_keys.slice(*instance_value.validations.keys)
23
+
24
+ # we validate each object in the array
25
+ # if boolean found as any of the validations we force value to boolean - if present
26
+ instance_value.boolean_attrs.each do |boolean_attr|
27
+ value[boolean_attr] = HashyValueValidator.get_boolean_value(t[boolean_attr]) if value.key?(boolean_attr)
28
+ end
29
+
30
+ # keep track of unique values and add error if needed
31
+ instance_value.unique_attrs.each_key do |unique_attr|
32
+ if instance_value.unique_attrs[unique_attr].include?(value[unique_attr])
33
+ record.errors.add(attribute, "'#{unique_attr}' not unique")
34
+ else
35
+ instance_value.unique_attrs[unique_attr] << t[unique_attr]
36
+ end
37
+ end
38
+
39
+ # use default hash validator
40
+ validator = HashValidator.validate(value, instance_value.validations)
41
+ unless validator.valid?
42
+ validator.errors.each { |k, v| record.errors.add(attribute, "'#{k}' #{v}") }
43
+ end
44
+
45
+ # update the value even if errors found
46
+ # we use send write param so we also support attr_accessor attributes
47
+ record.send("#{attribute}=", value)
48
+ end
49
+ end
@@ -1,20 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class HashyValueValidator
4
- def initialize(value)
4
+ def initialize(value, options = {})
5
5
  @value = value.blank? ? [] : value
6
6
  @valid = true
7
7
  @reason = nil
8
+ @validations = {}
9
+ @unique_attrs = {}
10
+ @boolean_attrs = []
8
11
 
9
12
  check_parse_value
10
- check_is_array
13
+ define_validations(options)
11
14
  end
12
15
 
13
16
  def valid?
14
17
  @valid
15
18
  end
16
19
 
17
- attr_reader :value, :reason
20
+ attr_reader :value, :reason, :validations, :unique_attrs, :boolean_attrs
21
+
22
+ def self.get_boolean_value(value)
23
+ return true if [true, "true"].include?(value)
24
+ return false if [false, "false"].include?(value)
25
+
26
+ nil
27
+ end
18
28
 
19
29
  private
20
30
 
@@ -25,10 +35,38 @@ class HashyValueValidator
25
35
  @reason = :invalid
26
36
  end
27
37
 
28
- def check_is_array
29
- return if @value.is_a?(Array)
38
+ def define_validations(options)
39
+ # look for boolean and unique validator entries
40
+ unique_attrs = {}
41
+ boolean_attrs = []
42
+ validations =
43
+ # force validator keys to be strings
44
+ options.stringify_keys.map do |val_attr, val|
45
+ is_multiple = val.is_a?(HashValidator::Validations::Multiple)
46
+ if (is_multiple && val.validations.include?("boolean")) || (val.is_a?(String) && val == "boolean")
47
+ boolean_attrs << val_attr
48
+ [val_attr, val]
49
+ elsif is_multiple && val.validations.include?("unique")
50
+ # if unique key present, then remove that entry
51
+ # (since its not from HashValidator standard) and keep its history
52
+ unique_attrs[val_attr] ||= []
53
+ # we have to make a new object to remove the unique entry,
54
+ # because deleting it directly from the original object
55
+ # (val) would result into deleting the verification forever
56
+ new_val = HashValidator::Validations::Multiple.new(val.validations.reject { |v| v == "unique" })
57
+ # return the value
58
+ val.validations.blank? ? nil : [val_attr, new_val]
59
+ elsif val.is_a?(String) && val == "unique"
60
+ # same as above but substring
61
+ unique_attrs[val_attr] ||= []
62
+ nil
63
+ else
64
+ [val_attr, val]
65
+ end
66
+ end.compact.to_h
30
67
 
31
- @valid = false
32
- @reason = :not_an_array
68
+ @validations = validations
69
+ @unique_attrs = unique_attrs
70
+ @boolean_attrs = boolean_attrs
33
71
  end
34
72
  end
@@ -4,7 +4,7 @@ module HashyValidator
4
4
  module Version
5
5
  MAJOR = 0
6
6
  MINOR = 1
7
- PATCH = 3
7
+ PATCH = 5
8
8
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
9
9
  end
10
10
  end
@@ -4,3 +4,4 @@ require "active_record"
4
4
  require "hash_validator"
5
5
  require_relative "hashy_validator/hashy_value_validator"
6
6
  require_relative "hashy_validator/hashy_array_validator"
7
+ require_relative "hashy_validator/hashy_object_validator"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashy_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Flecto Team
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: '2.14'
117
+ - !ruby/object:Gem::Dependency
118
+ name: pry
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 0.14.1
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 0.14.1
117
131
  - !ruby/object:Gem::Dependency
118
132
  name: minitest
119
133
  requirement: !ruby/object:Gem::Requirement
@@ -142,6 +156,7 @@ files:
142
156
  - hashy_validator.gemspec
143
157
  - lib/hashy_validator.rb
144
158
  - lib/hashy_validator/hashy_array_validator.rb
159
+ - lib/hashy_validator/hashy_object_validator.rb
145
160
  - lib/hashy_validator/hashy_value_validator.rb
146
161
  - lib/hashy_validator/version.rb
147
162
  homepage: