hashy_validator 0.1.3 → 0.1.5

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: 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: