hash_validator 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 +4 -4
- data/.github/workflows/ruby.yml +27 -0
- data/.ruby-version +1 -1
- data/Plan.md +309 -0
- data/README.md +157 -60
- data/hash_validator.gemspec +5 -5
- data/lib/hash_validator/validators/alpha_validator.rb +23 -0
- data/lib/hash_validator/validators/alphanumeric_validator.rb +23 -0
- data/lib/hash_validator/validators/array_validator.rb +15 -1
- data/lib/hash_validator/validators/digits_validator.rb +23 -0
- data/lib/hash_validator/validators/hash_validator.rb +6 -1
- data/lib/hash_validator/validators/hex_color_validator.rb +23 -0
- data/lib/hash_validator/validators/json_validator.rb +28 -0
- data/lib/hash_validator/validators/url_validator.rb +28 -0
- data/lib/hash_validator/validators.rb +7 -1
- data/lib/hash_validator/version.rb +1 -1
- data/spec/spec_helper.rb +1 -4
- data/spec/validators/alpha_validator_spec.rb +93 -0
- data/spec/validators/alphanumeric_validator_spec.rb +99 -0
- data/spec/validators/digits_validator_spec.rb +99 -0
- data/spec/validators/hash_validator_spec.rb +102 -0
- data/spec/validators/hex_color_validator_spec.rb +111 -0
- data/spec/validators/json_validator_spec.rb +88 -0
- data/spec/validators/url_validator_spec.rb +75 -0
- metadata +26 -19
- data/.travis.yml +0 -5
@@ -46,7 +46,21 @@ class HashValidator::Validator::ArrayValidator < HashValidator::Validator::Base
|
|
46
46
|
return if array_spec.empty?
|
47
47
|
|
48
48
|
size_spec = array_spec[:size]
|
49
|
-
|
49
|
+
|
50
|
+
size_spec_present = case size_spec
|
51
|
+
when String
|
52
|
+
!object.strip.empty?
|
53
|
+
when NilClass
|
54
|
+
false
|
55
|
+
when Numeric
|
56
|
+
true
|
57
|
+
when Array, Hash
|
58
|
+
!object.empty?
|
59
|
+
else
|
60
|
+
!!object
|
61
|
+
end
|
62
|
+
|
63
|
+
if size_spec_present
|
50
64
|
unless value.size == size_spec
|
51
65
|
errors[key] = "The required size of array is #{size_spec} but is #{value.size}."
|
52
66
|
return
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class HashValidator::Validator::DigitsValidator < HashValidator::Validator::Base
|
2
|
+
def initialize
|
3
|
+
super('digits') # The name of the validator
|
4
|
+
end
|
5
|
+
|
6
|
+
def presence_error_message
|
7
|
+
'must contain only digits'
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate(key, value, _validations, errors)
|
11
|
+
unless value.is_a?(String) && valid_digits?(value)
|
12
|
+
errors[key] = presence_error_message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def valid_digits?(value)
|
19
|
+
/\A\d+\z/.match?(value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
HashValidator.append_validator(HashValidator::Validator::DigitsValidator.new)
|
@@ -4,10 +4,15 @@ class HashValidator::Validator::HashValidator < HashValidator::Validator::Base
|
|
4
4
|
end
|
5
5
|
|
6
6
|
def should_validate?(rhs)
|
7
|
-
rhs.is_a?(Hash)
|
7
|
+
rhs.is_a?(Hash) || (defined?(ActionController::Parameters) && rhs.is_a?(ActionController::Parameters))
|
8
8
|
end
|
9
9
|
|
10
10
|
def validate(key, value, validations, errors)
|
11
|
+
# Convert ActionController::Parameters to Hash if needed
|
12
|
+
if !value.is_a?(Hash) && defined?(ActionController::Parameters) && value.is_a?(ActionController::Parameters)
|
13
|
+
value = value.to_unsafe_h
|
14
|
+
end
|
15
|
+
|
11
16
|
# Validate hash
|
12
17
|
unless value.is_a?(Hash)
|
13
18
|
errors[key] = presence_error_message
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class HashValidator::Validator::HexColorValidator < HashValidator::Validator::Base
|
2
|
+
def initialize
|
3
|
+
super('hex_color') # The name of the validator
|
4
|
+
end
|
5
|
+
|
6
|
+
def presence_error_message
|
7
|
+
'is not a valid hex color'
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate(key, value, _validations, errors)
|
11
|
+
unless value.is_a?(String) && valid_hex_color?(value)
|
12
|
+
errors[key] = presence_error_message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def valid_hex_color?(value)
|
19
|
+
/\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/.match?(value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
HashValidator.append_validator(HashValidator::Validator::HexColorValidator.new)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class HashValidator::Validator::JsonValidator < HashValidator::Validator::Base
|
4
|
+
def initialize
|
5
|
+
super('json') # The name of the validator
|
6
|
+
end
|
7
|
+
|
8
|
+
def presence_error_message
|
9
|
+
'is not valid JSON'
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate(key, value, _validations, errors)
|
13
|
+
unless value.is_a?(String) && valid_json?(value)
|
14
|
+
errors[key] = presence_error_message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def valid_json?(value)
|
21
|
+
JSON.parse(value)
|
22
|
+
true
|
23
|
+
rescue JSON::ParserError
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
HashValidator.append_validator(HashValidator::Validator::JsonValidator.new)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
class HashValidator::Validator::UrlValidator < HashValidator::Validator::Base
|
4
|
+
def initialize
|
5
|
+
super('url') # The name of the validator
|
6
|
+
end
|
7
|
+
|
8
|
+
def presence_error_message
|
9
|
+
'is not a valid URL'
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate(key, value, _validations, errors)
|
13
|
+
unless value.is_a?(String) && valid_url?(value)
|
14
|
+
errors[key] = presence_error_message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def valid_url?(value)
|
21
|
+
uri = URI.parse(value)
|
22
|
+
%w[http https ftp].include?(uri.scheme)
|
23
|
+
rescue URI::InvalidURIError
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
HashValidator.append_validator(HashValidator::Validator::UrlValidator.new)
|
@@ -37,4 +37,10 @@ require 'hash_validator/validators/lambda_validator'
|
|
37
37
|
require 'hash_validator/validators/optional_validator'
|
38
38
|
require 'hash_validator/validators/many_validator'
|
39
39
|
require 'hash_validator/validators/multiple_validator'
|
40
|
-
require 'hash_validator/validators/array_validator'
|
40
|
+
require 'hash_validator/validators/array_validator'
|
41
|
+
require 'hash_validator/validators/url_validator'
|
42
|
+
require 'hash_validator/validators/json_validator'
|
43
|
+
require 'hash_validator/validators/hex_color_validator'
|
44
|
+
require 'hash_validator/validators/alphanumeric_validator'
|
45
|
+
require 'hash_validator/validators/alpha_validator'
|
46
|
+
require 'hash_validator/validators/digits_validator'
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'coveralls'
|
2
|
-
Coveralls.wear!
|
3
|
-
|
4
1
|
require 'rubygems'
|
5
2
|
require 'hash_validator'
|
6
3
|
require 'hash_validator_spec_helper'
|
@@ -9,6 +6,6 @@ RSpec.configure do |config|
|
|
9
6
|
config.run_all_when_everything_filtered = true
|
10
7
|
config.filter_run :focus
|
11
8
|
config.order = 'random'
|
12
|
-
|
9
|
+
|
13
10
|
config.include HashValidatorSpecHelper
|
14
11
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HashValidator::Validator::AlphaValidator do
|
4
|
+
let(:validator) { HashValidator::Validator::AlphaValidator.new }
|
5
|
+
|
6
|
+
context 'valid alpha strings' do
|
7
|
+
it 'validates lowercase letters' do
|
8
|
+
errors = {}
|
9
|
+
validator.validate('key', 'abc', {}, errors)
|
10
|
+
expect(errors).to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'validates uppercase letters' do
|
14
|
+
errors = {}
|
15
|
+
validator.validate('key', 'ABC', {}, errors)
|
16
|
+
expect(errors).to be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'validates mixed case letters' do
|
20
|
+
errors = {}
|
21
|
+
validator.validate('key', 'AbC', {}, errors)
|
22
|
+
expect(errors).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'validates single letter' do
|
26
|
+
errors = {}
|
27
|
+
validator.validate('key', 'a', {}, errors)
|
28
|
+
expect(errors).to be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'validates long strings' do
|
32
|
+
errors = {}
|
33
|
+
validator.validate('key', 'HelloWorld', {}, errors)
|
34
|
+
expect(errors).to be_empty
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'invalid alpha strings' do
|
39
|
+
it 'rejects non-string values' do
|
40
|
+
errors = {}
|
41
|
+
validator.validate('key', 123, {}, errors)
|
42
|
+
expect(errors['key']).to eq('must contain only letters')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'rejects nil values' do
|
46
|
+
errors = {}
|
47
|
+
validator.validate('key', nil, {}, errors)
|
48
|
+
expect(errors['key']).to eq('must contain only letters')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'rejects strings with numbers' do
|
52
|
+
errors = {}
|
53
|
+
validator.validate('key', 'abc123', {}, errors)
|
54
|
+
expect(errors['key']).to eq('must contain only letters')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'rejects strings with spaces' do
|
58
|
+
errors = {}
|
59
|
+
validator.validate('key', 'abc def', {}, errors)
|
60
|
+
expect(errors['key']).to eq('must contain only letters')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'rejects strings with special characters' do
|
64
|
+
errors = {}
|
65
|
+
validator.validate('key', 'abc!', {}, errors)
|
66
|
+
expect(errors['key']).to eq('must contain only letters')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'rejects strings with hyphens' do
|
70
|
+
errors = {}
|
71
|
+
validator.validate('key', 'abc-def', {}, errors)
|
72
|
+
expect(errors['key']).to eq('must contain only letters')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'rejects strings with underscores' do
|
76
|
+
errors = {}
|
77
|
+
validator.validate('key', 'abc_def', {}, errors)
|
78
|
+
expect(errors['key']).to eq('must contain only letters')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'rejects empty strings' do
|
82
|
+
errors = {}
|
83
|
+
validator.validate('key', '', {}, errors)
|
84
|
+
expect(errors['key']).to eq('must contain only letters')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'rejects strings with periods' do
|
88
|
+
errors = {}
|
89
|
+
validator.validate('key', 'abc.def', {}, errors)
|
90
|
+
expect(errors['key']).to eq('must contain only letters')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HashValidator::Validator::AlphanumericValidator do
|
4
|
+
let(:validator) { HashValidator::Validator::AlphanumericValidator.new }
|
5
|
+
|
6
|
+
context 'valid alphanumeric strings' do
|
7
|
+
it 'validates letters only' do
|
8
|
+
errors = {}
|
9
|
+
validator.validate('key', 'abc', {}, errors)
|
10
|
+
expect(errors).to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'validates numbers only' do
|
14
|
+
errors = {}
|
15
|
+
validator.validate('key', '123', {}, errors)
|
16
|
+
expect(errors).to be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'validates mixed letters and numbers' do
|
20
|
+
errors = {}
|
21
|
+
validator.validate('key', 'abc123', {}, errors)
|
22
|
+
expect(errors).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'validates uppercase letters' do
|
26
|
+
errors = {}
|
27
|
+
validator.validate('key', 'ABC', {}, errors)
|
28
|
+
expect(errors).to be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'validates mixed case letters' do
|
32
|
+
errors = {}
|
33
|
+
validator.validate('key', 'AbC123', {}, errors)
|
34
|
+
expect(errors).to be_empty
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'validates single character' do
|
38
|
+
errors = {}
|
39
|
+
validator.validate('key', 'a', {}, errors)
|
40
|
+
expect(errors).to be_empty
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'validates single digit' do
|
44
|
+
errors = {}
|
45
|
+
validator.validate('key', '1', {}, errors)
|
46
|
+
expect(errors).to be_empty
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'invalid alphanumeric strings' do
|
51
|
+
it 'rejects non-string values' do
|
52
|
+
errors = {}
|
53
|
+
validator.validate('key', 123, {}, errors)
|
54
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'rejects nil values' do
|
58
|
+
errors = {}
|
59
|
+
validator.validate('key', nil, {}, errors)
|
60
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'rejects strings with spaces' do
|
64
|
+
errors = {}
|
65
|
+
validator.validate('key', 'abc 123', {}, errors)
|
66
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'rejects strings with special characters' do
|
70
|
+
errors = {}
|
71
|
+
validator.validate('key', 'abc!123', {}, errors)
|
72
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'rejects strings with hyphens' do
|
76
|
+
errors = {}
|
77
|
+
validator.validate('key', 'abc-123', {}, errors)
|
78
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'rejects strings with underscores' do
|
82
|
+
errors = {}
|
83
|
+
validator.validate('key', 'abc_123', {}, errors)
|
84
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'rejects empty strings' do
|
88
|
+
errors = {}
|
89
|
+
validator.validate('key', '', {}, errors)
|
90
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'rejects strings with periods' do
|
94
|
+
errors = {}
|
95
|
+
validator.validate('key', 'abc.123', {}, errors)
|
96
|
+
expect(errors['key']).to eq('must contain only letters and numbers')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HashValidator::Validator::DigitsValidator do
|
4
|
+
let(:validator) { HashValidator::Validator::DigitsValidator.new }
|
5
|
+
|
6
|
+
context 'valid digit strings' do
|
7
|
+
it 'validates single digit' do
|
8
|
+
errors = {}
|
9
|
+
validator.validate('key', '1', {}, errors)
|
10
|
+
expect(errors).to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'validates multiple digits' do
|
14
|
+
errors = {}
|
15
|
+
validator.validate('key', '123', {}, errors)
|
16
|
+
expect(errors).to be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'validates zero' do
|
20
|
+
errors = {}
|
21
|
+
validator.validate('key', '0', {}, errors)
|
22
|
+
expect(errors).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'validates long number strings' do
|
26
|
+
errors = {}
|
27
|
+
validator.validate('key', '1234567890', {}, errors)
|
28
|
+
expect(errors).to be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'validates leading zeros' do
|
32
|
+
errors = {}
|
33
|
+
validator.validate('key', '0123', {}, errors)
|
34
|
+
expect(errors).to be_empty
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'invalid digit strings' do
|
39
|
+
it 'rejects non-string values' do
|
40
|
+
errors = {}
|
41
|
+
validator.validate('key', 123, {}, errors)
|
42
|
+
expect(errors['key']).to eq('must contain only digits')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'rejects nil values' do
|
46
|
+
errors = {}
|
47
|
+
validator.validate('key', nil, {}, errors)
|
48
|
+
expect(errors['key']).to eq('must contain only digits')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'rejects strings with letters' do
|
52
|
+
errors = {}
|
53
|
+
validator.validate('key', '123abc', {}, errors)
|
54
|
+
expect(errors['key']).to eq('must contain only digits')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'rejects strings with spaces' do
|
58
|
+
errors = {}
|
59
|
+
validator.validate('key', '123 456', {}, errors)
|
60
|
+
expect(errors['key']).to eq('must contain only digits')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'rejects strings with special characters' do
|
64
|
+
errors = {}
|
65
|
+
validator.validate('key', '123!', {}, errors)
|
66
|
+
expect(errors['key']).to eq('must contain only digits')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'rejects strings with hyphens' do
|
70
|
+
errors = {}
|
71
|
+
validator.validate('key', '123-456', {}, errors)
|
72
|
+
expect(errors['key']).to eq('must contain only digits')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'rejects strings with periods' do
|
76
|
+
errors = {}
|
77
|
+
validator.validate('key', '123.456', {}, errors)
|
78
|
+
expect(errors['key']).to eq('must contain only digits')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'rejects empty strings' do
|
82
|
+
errors = {}
|
83
|
+
validator.validate('key', '', {}, errors)
|
84
|
+
expect(errors['key']).to eq('must contain only digits')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'rejects negative signs' do
|
88
|
+
errors = {}
|
89
|
+
validator.validate('key', '-123', {}, errors)
|
90
|
+
expect(errors['key']).to eq('must contain only digits')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'rejects positive signs' do
|
94
|
+
errors = {}
|
95
|
+
validator.validate('key', '+123', {}, errors)
|
96
|
+
expect(errors['key']).to eq('must contain only digits')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ActionController::Parameters support' do
|
4
|
+
# Mock ActionController::Parameters for testing
|
5
|
+
let(:mock_params_class) do
|
6
|
+
Class.new do
|
7
|
+
attr_reader :data
|
8
|
+
|
9
|
+
def initialize(data)
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
@data[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def keys
|
18
|
+
@data.keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_unsafe_h
|
22
|
+
@data
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_a?(klass)
|
26
|
+
return true if klass.name == 'ActionController::Parameters'
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def class
|
31
|
+
OpenStruct.new(name: 'ActionController::Parameters')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
before do
|
37
|
+
# Define ActionController::Parameters constant for testing
|
38
|
+
unless defined?(ActionController::Parameters)
|
39
|
+
ActionController = Module.new unless defined?(ActionController)
|
40
|
+
ActionController.const_set(:Parameters, mock_params_class)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should validate ActionController::Parameters objects' do
|
45
|
+
params = ActionController::Parameters.new({ name: 'John', age: 30 })
|
46
|
+
validations = { name: 'string', age: 'integer' }
|
47
|
+
|
48
|
+
validator = HashValidator.validate(params, validations)
|
49
|
+
|
50
|
+
expect(validator.valid?).to be true
|
51
|
+
expect(validator.errors).to be_empty
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should handle nested ActionController::Parameters' do
|
55
|
+
nested_params = ActionController::Parameters.new({ theme: 'dark' })
|
56
|
+
params = ActionController::Parameters.new({
|
57
|
+
name: 'John',
|
58
|
+
preferences: nested_params
|
59
|
+
})
|
60
|
+
|
61
|
+
validations = {
|
62
|
+
name: 'string',
|
63
|
+
preferences: { theme: 'string' }
|
64
|
+
}
|
65
|
+
|
66
|
+
validator = HashValidator.validate(params, validations)
|
67
|
+
|
68
|
+
expect(validator.valid?).to be true
|
69
|
+
expect(validator.errors).to be_empty
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should validate ActionController::Parameters with our new validators' do
|
73
|
+
params = ActionController::Parameters.new({
|
74
|
+
name: 'John',
|
75
|
+
email: 'john@example.com',
|
76
|
+
website: 'https://john.com',
|
77
|
+
zip_code: '12345'
|
78
|
+
})
|
79
|
+
|
80
|
+
validations = {
|
81
|
+
name: 'alpha',
|
82
|
+
email: 'email',
|
83
|
+
website: 'url',
|
84
|
+
zip_code: 'digits'
|
85
|
+
}
|
86
|
+
|
87
|
+
validator = HashValidator.validate(params, validations)
|
88
|
+
|
89
|
+
expect(validator.valid?).to be true
|
90
|
+
expect(validator.errors).to be_empty
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should still work with regular hashes' do
|
94
|
+
hash = { name: 'John', age: 30 }
|
95
|
+
validations = { name: 'string', age: 'integer' }
|
96
|
+
|
97
|
+
validator = HashValidator.validate(hash, validations)
|
98
|
+
|
99
|
+
expect(validator.valid?).to be true
|
100
|
+
expect(validator.errors).to be_empty
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HashValidator::Validator::HexColorValidator do
|
4
|
+
let(:validator) { HashValidator::Validator::HexColorValidator.new }
|
5
|
+
|
6
|
+
context 'valid hex colors' do
|
7
|
+
it 'validates 6-digit hex colors (lowercase)' do
|
8
|
+
errors = {}
|
9
|
+
validator.validate('key', '#ff0000', {}, errors)
|
10
|
+
expect(errors).to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'validates 6-digit hex colors (uppercase)' do
|
14
|
+
errors = {}
|
15
|
+
validator.validate('key', '#FF0000', {}, errors)
|
16
|
+
expect(errors).to be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'validates 6-digit hex colors (mixed case)' do
|
20
|
+
errors = {}
|
21
|
+
validator.validate('key', '#Ff0000', {}, errors)
|
22
|
+
expect(errors).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'validates 3-digit hex colors (lowercase)' do
|
26
|
+
errors = {}
|
27
|
+
validator.validate('key', '#f00', {}, errors)
|
28
|
+
expect(errors).to be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'validates 3-digit hex colors (uppercase)' do
|
32
|
+
errors = {}
|
33
|
+
validator.validate('key', '#F00', {}, errors)
|
34
|
+
expect(errors).to be_empty
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'validates black color' do
|
38
|
+
errors = {}
|
39
|
+
validator.validate('key', '#000000', {}, errors)
|
40
|
+
expect(errors).to be_empty
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'validates white color' do
|
44
|
+
errors = {}
|
45
|
+
validator.validate('key', '#ffffff', {}, errors)
|
46
|
+
expect(errors).to be_empty
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'validates complex hex colors' do
|
50
|
+
errors = {}
|
51
|
+
validator.validate('key', '#3a7bd4', {}, errors)
|
52
|
+
expect(errors).to be_empty
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'invalid hex colors' do
|
57
|
+
it 'rejects non-string values' do
|
58
|
+
errors = {}
|
59
|
+
validator.validate('key', 123, {}, errors)
|
60
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'rejects nil values' do
|
64
|
+
errors = {}
|
65
|
+
validator.validate('key', nil, {}, errors)
|
66
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'rejects hex colors without hash' do
|
70
|
+
errors = {}
|
71
|
+
validator.validate('key', 'ff0000', {}, errors)
|
72
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'rejects invalid length (4 digits)' do
|
76
|
+
errors = {}
|
77
|
+
validator.validate('key', '#ff00', {}, errors)
|
78
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'rejects invalid length (5 digits)' do
|
82
|
+
errors = {}
|
83
|
+
validator.validate('key', '#ff000', {}, errors)
|
84
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'rejects invalid length (7 digits)' do
|
88
|
+
errors = {}
|
89
|
+
validator.validate('key', '#ff00000', {}, errors)
|
90
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'rejects invalid characters' do
|
94
|
+
errors = {}
|
95
|
+
validator.validate('key', '#gg0000', {}, errors)
|
96
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'rejects empty strings' do
|
100
|
+
errors = {}
|
101
|
+
validator.validate('key', '', {}, errors)
|
102
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'rejects just hash symbol' do
|
106
|
+
errors = {}
|
107
|
+
validator.validate('key', '#', {}, errors)
|
108
|
+
expect(errors['key']).to eq('is not a valid hex color')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|