hash_validator 1.2.0 → 2.0.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +173 -12
  3. data/lib/hash_validator/configuration.rb +16 -0
  4. data/lib/hash_validator/validators/alpha_validator.rb +4 -12
  5. data/lib/hash_validator/validators/alphanumeric_validator.rb +4 -12
  6. data/lib/hash_validator/validators/array_validator.rb +1 -1
  7. data/lib/hash_validator/validators/base.rb +28 -3
  8. data/lib/hash_validator/validators/boolean_validator.rb +3 -5
  9. data/lib/hash_validator/validators/class_validator.rb +1 -1
  10. data/lib/hash_validator/validators/digits_validator.rb +4 -12
  11. data/lib/hash_validator/validators/dynamic_func_validator.rb +26 -0
  12. data/lib/hash_validator/validators/dynamic_pattern_validator.rb +23 -0
  13. data/lib/hash_validator/validators/email_validator.rb +4 -6
  14. data/lib/hash_validator/validators/enumerable_validator.rb +4 -6
  15. data/lib/hash_validator/validators/hash_validator.rb +2 -2
  16. data/lib/hash_validator/validators/hex_color_validator.rb +4 -12
  17. data/lib/hash_validator/validators/ip_validator.rb +22 -0
  18. data/lib/hash_validator/validators/ipv4_validator.rb +18 -0
  19. data/lib/hash_validator/validators/ipv6_validator.rb +22 -0
  20. data/lib/hash_validator/validators/json_validator.rb +4 -11
  21. data/lib/hash_validator/validators/lambda_validator.rb +5 -8
  22. data/lib/hash_validator/validators/many_validator.rb +3 -3
  23. data/lib/hash_validator/validators/multiple_validator.rb +1 -1
  24. data/lib/hash_validator/validators/optional_validator.rb +1 -1
  25. data/lib/hash_validator/validators/presence_validator.rb +4 -6
  26. data/lib/hash_validator/validators/regex_validator.rb +4 -6
  27. data/lib/hash_validator/validators/simple_type_validators.rb +1 -1
  28. data/lib/hash_validator/validators/simple_validator.rb +2 -4
  29. data/lib/hash_validator/validators/url_validator.rb +4 -11
  30. data/lib/hash_validator/validators.rb +40 -4
  31. data/lib/hash_validator/version.rb +1 -1
  32. data/lib/hash_validator.rb +1 -0
  33. data/spec/configuration_spec.rb +189 -0
  34. data/spec/hash_validator_spec.rb +4 -4
  35. data/spec/validators/base_spec.rb +2 -2
  36. data/spec/validators/dynamic_func_validator_spec.rb +252 -0
  37. data/spec/validators/dynamic_pattern_validator_spec.rb +150 -0
  38. data/spec/validators/ip_validator_spec.rb +105 -0
  39. data/spec/validators/ipv4_validator_spec.rb +99 -0
  40. data/spec/validators/ipv6_validator_spec.rb +99 -0
  41. data/spec/validators/user_defined_spec.rb +2 -2
  42. metadata +20 -3
  43. data/Plan.md +0 -309
@@ -11,7 +11,7 @@ describe 'User-defined validator' do
11
11
 
12
12
  def validate(key, value, validations, errors)
13
13
  unless value.is_a?(Integer) && value.odd?
14
- errors[key] = presence_error_message
14
+ errors[key] = error_message
15
15
  end
16
16
  end
17
17
  end
@@ -72,7 +72,7 @@ describe 'User-defined validator' do
72
72
  end
73
73
 
74
74
  describe 'Integrating with the entire validation system' do
75
- before { HashValidator.append_validator(validator) rescue nil } # rescue to prevent: validators need to have unique names
75
+ before { HashValidator.add_validator(validator) rescue nil } # rescue to prevent: validators need to have unique names
76
76
 
77
77
  it 'can be looked up using #validator_for' do
78
78
  expect(HashValidator.validator_for('odd')).to be_a_kind_of(HashValidator::Validator::OddValidator)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hash_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Brooks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-08-20 00:00:00.000000000 Z
11
+ date: 2025-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,12 +65,12 @@ files:
65
65
  - ".ruby-version"
66
66
  - Gemfile
67
67
  - LICENSE.txt
68
- - Plan.md
69
68
  - README.md
70
69
  - Rakefile
71
70
  - hash_validator.gemspec
72
71
  - lib/hash_validator.rb
73
72
  - lib/hash_validator/base.rb
73
+ - lib/hash_validator/configuration.rb
74
74
  - lib/hash_validator/validations.rb
75
75
  - lib/hash_validator/validations/many.rb
76
76
  - lib/hash_validator/validations/multiple.rb
@@ -83,10 +83,15 @@ files:
83
83
  - lib/hash_validator/validators/boolean_validator.rb
84
84
  - lib/hash_validator/validators/class_validator.rb
85
85
  - lib/hash_validator/validators/digits_validator.rb
86
+ - lib/hash_validator/validators/dynamic_func_validator.rb
87
+ - lib/hash_validator/validators/dynamic_pattern_validator.rb
86
88
  - lib/hash_validator/validators/email_validator.rb
87
89
  - lib/hash_validator/validators/enumerable_validator.rb
88
90
  - lib/hash_validator/validators/hash_validator.rb
89
91
  - lib/hash_validator/validators/hex_color_validator.rb
92
+ - lib/hash_validator/validators/ip_validator.rb
93
+ - lib/hash_validator/validators/ipv4_validator.rb
94
+ - lib/hash_validator/validators/ipv6_validator.rb
90
95
  - lib/hash_validator/validators/json_validator.rb
91
96
  - lib/hash_validator/validators/lambda_validator.rb
92
97
  - lib/hash_validator/validators/many_validator.rb
@@ -98,6 +103,7 @@ files:
98
103
  - lib/hash_validator/validators/simple_validator.rb
99
104
  - lib/hash_validator/validators/url_validator.rb
100
105
  - lib/hash_validator/version.rb
106
+ - spec/configuration_spec.rb
101
107
  - spec/hash_validator_spec.rb
102
108
  - spec/hash_validator_spec_helper.rb
103
109
  - spec/spec_helper.rb
@@ -108,10 +114,15 @@ files:
108
114
  - spec/validators/boolean_spec.rb
109
115
  - spec/validators/class_spec.rb
110
116
  - spec/validators/digits_validator_spec.rb
117
+ - spec/validators/dynamic_func_validator_spec.rb
118
+ - spec/validators/dynamic_pattern_validator_spec.rb
111
119
  - spec/validators/email_spec.rb
112
120
  - spec/validators/hash_validator_spec.rb
113
121
  - spec/validators/hex_color_validator_spec.rb
114
122
  - spec/validators/in_enumerable_spec.rb
123
+ - spec/validators/ip_validator_spec.rb
124
+ - spec/validators/ipv4_validator_spec.rb
125
+ - spec/validators/ipv6_validator_spec.rb
115
126
  - spec/validators/json_validator_spec.rb
116
127
  - spec/validators/lambda_spec.rb
117
128
  - spec/validators/many_spec.rb
@@ -147,6 +158,7 @@ signing_key:
147
158
  specification_version: 4
148
159
  summary: Ruby library to validate hashes (Hash) against user-defined requirements
149
160
  test_files:
161
+ - spec/configuration_spec.rb
150
162
  - spec/hash_validator_spec.rb
151
163
  - spec/hash_validator_spec_helper.rb
152
164
  - spec/spec_helper.rb
@@ -157,10 +169,15 @@ test_files:
157
169
  - spec/validators/boolean_spec.rb
158
170
  - spec/validators/class_spec.rb
159
171
  - spec/validators/digits_validator_spec.rb
172
+ - spec/validators/dynamic_func_validator_spec.rb
173
+ - spec/validators/dynamic_pattern_validator_spec.rb
160
174
  - spec/validators/email_spec.rb
161
175
  - spec/validators/hash_validator_spec.rb
162
176
  - spec/validators/hex_color_validator_spec.rb
163
177
  - spec/validators/in_enumerable_spec.rb
178
+ - spec/validators/ip_validator_spec.rb
179
+ - spec/validators/ipv4_validator_spec.rb
180
+ - spec/validators/ipv6_validator_spec.rb
164
181
  - spec/validators/json_validator_spec.rb
165
182
  - spec/validators/lambda_spec.rb
166
183
  - spec/validators/many_spec.rb
data/Plan.md DELETED
@@ -1,309 +0,0 @@
1
- # Hash Validator Enhancement Plan - Living Document
2
-
3
- ## Document Instructions
4
- **This is a living plan document.** It should be updated throughout the implementation process to track:
5
- - Current progress and completion status
6
- - Any deviations or improvements discovered during implementation
7
- - Lessons learned that may benefit subsequent phases
8
- - Test results and quality check outcomes
9
-
10
- **Update Protocol:**
11
- 1. Mark tasks as `[x]` when completed
12
- 2. Add notes in **Implementation Notes** sections for important discoveries
13
- 3. Update status indicators for each phase
14
- 4. Document any blockers or changes in approach
15
-
16
- ## Overall Objective
17
- Add 11 new validators to the hash_validator gem to expand its validation capabilities for common use cases.
18
-
19
- ## Phase Structure
20
- Between each major phase:
21
- 1. Run full test suite: `rake spec`
22
- 2. Verify no breaking changes to existing functionality
23
- 3. Provide summary to user
24
- 4. Request approval before proceeding to next phase
25
-
26
- ---
27
-
28
- ## Phase 1: Simple String Pattern Validators
29
- **Status:** [ ] Not Started | [ ] In Progress | [x] Completed
30
- **Validators:** URL, JSON, Hex Color, Alphanumeric, Alpha, Digits
31
-
32
- ### Tasks:
33
- - [x] Create URL validator (`lib/hash_validator/validators/url_validator.rb`)
34
- - Validation: Use `URI.parse` and check for valid scheme
35
- - Error message: "is not a valid URL"
36
- - Accept: http, https, ftp schemes
37
-
38
- - [x] Create JSON validator (`lib/hash_validator/validators/json_validator.rb`)
39
- - Validation: `JSON.parse(value)` with rescue
40
- - Error message: "is not valid JSON"
41
- - Must be string type first
42
-
43
- - [x] Create Hex Color validator (`lib/hash_validator/validators/hex_color_validator.rb`)
44
- - Validation: Regex `/\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/`
45
- - Error message: "is not a valid hex color"
46
- - Accept: #RGB and #RRGGBB formats
47
-
48
- - [x] Create Alphanumeric validator (`lib/hash_validator/validators/alphanumeric_validator.rb`)
49
- - Validation: Regex `/\A[a-zA-Z0-9]+\z/`
50
- - Error message: "must contain only letters and numbers"
51
-
52
- - [x] Create Alpha validator (`lib/hash_validator/validators/alpha_validator.rb`)
53
- - Validation: Regex `/\A[a-zA-Z]+\z/`
54
- - Error message: "must contain only letters"
55
-
56
- - [x] Create Digits validator (`lib/hash_validator/validators/digits_validator.rb`)
57
- - Validation: Regex `/\A\d+\z/`
58
- - Error message: "must contain only digits"
59
-
60
- ### Tests:
61
- - [x] Write specs for each validator in `spec/validators/[validator_name]_spec.rb`
62
- - [x] Test valid inputs, invalid inputs, nil values, wrong types
63
- - [x] Run test suite and ensure all pass
64
-
65
- ### Registration:
66
- - [x] Add requires to `lib/hash_validator/validators.rb`
67
- - [x] Ensure validators auto-register via `HashValidator.append_validator`
68
-
69
- **Implementation Notes:**
70
- - **Ruby Version Updated:** Changed minimum Ruby requirement from 2.0.0 to 3.0.0 in gemspec
71
- - **URI Library:** Confirmed URI standard library is available in Ruby 3.0+ and works perfectly for URL validation
72
- - **JSON Library:** Confirmed JSON standard library is available in Ruby 3.0+ and works perfectly for JSON validation
73
- - **All Tests Pass:** 74 new tests added (70 validator tests + 4 Rails integration tests), all passing (451 total)
74
- - **Regex Patterns:** All regex patterns use `\A` and `\z` anchors for exact string matching
75
- - **Error Messages:** Follow established pattern ("is not a valid [type]" vs "must contain only [constraint]")
76
- - **Performance:** All validators use simple regex patterns for optimal performance
77
- - **Rails Integration:** Added ActionController::Parameters support - no more need for `.to_unsafe_h`
78
- - **README Updated:** Comprehensive table format with validation configs and example payloads, Rails controller example
79
- - **Documentation:** Added Requirements section, Quick Start, better Examples section structure
80
-
81
- ---
82
-
83
- ## Additional Improvements (Beyond Original Plan)
84
- **Status:** [x] Completed
85
- **Description:** Enhancements made during Phase 1 implementation
86
-
87
- ### Rails Integration Enhancement:
88
- - [x] **ActionController::Parameters Support**: Modified hash validator to automatically detect and handle Rails params
89
- - [x] **Seamless Conversion**: Internally calls `.to_unsafe_h` when `ActionController::Parameters` detected
90
- - [x] **Backward Compatibility**: Regular Hash validation continues to work unchanged
91
- - [x] **Integration Tests**: Added 4 comprehensive tests for Rails params support
92
-
93
- ### Documentation Improvements:
94
- - [x] **README Restructuring**: Better flow from Installation → Quick Start → Examples → Usage Table → Advanced Features
95
- - [x] **Usage Table Enhancement**: Three-column table with Validator, Configuration, and Example Payload
96
- - [x] **Rails Controller Example**: Practical example showing API parameter validation
97
- - [x] **Requirements Section**: Added Ruby 3.0+ requirement documentation
98
- - [x] **Quick Start Guide**: Simple 4-line example to get users started immediately
99
-
100
- ### Quality Improvements:
101
- - [x] **Test Coverage**: Increased from 447 to 451 total tests
102
- - [x] **Error Handling**: Verified all new validators provide clear, consistent error messages
103
- - [x] **Performance**: All new validators use efficient regex patterns
104
- - [x] **Integration**: Full compatibility testing with existing codebase
105
-
106
- **Implementation Notes:**
107
- - **Rails Support**: Uses `defined?(ActionController::Parameters)` for safe detection without requiring Rails
108
- - **User Experience**: Rails developers can now use `HashValidator.validate(params, validations)` directly
109
- - **Maintenance**: No breaking changes introduced, all existing APIs remain unchanged
110
-
111
- ---
112
-
113
- ## Phase 2: IP Address Validators
114
- **Status:** [ ] Not Started | [ ] In Progress | [ ] Completed
115
- **Validators:** IP (generic), IPv4, IPv6
116
-
117
- ### Tasks:
118
- - [ ] Create IPv4 validator (`lib/hash_validator/validators/ipv4_validator.rb`)
119
- - Validation: Check 4 octets, each 0-255
120
- - Regex: `/\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z/`
121
- - Error message: "is not a valid IPv4 address"
122
-
123
- - [ ] Create IPv6 validator (`lib/hash_validator/validators/ipv6_validator.rb`)
124
- - Validation: Standard IPv6 format including compressed notation
125
- - Consider using `IPAddr` class for validation
126
- - Error message: "is not a valid IPv6 address"
127
-
128
- - [ ] Create IP validator (`lib/hash_validator/validators/ip_validator.rb`)
129
- - Validation: Accept either IPv4 or IPv6
130
- - Can leverage IPv4 and IPv6 validators
131
- - Error message: "is not a valid IP address"
132
-
133
- ### Tests:
134
- - [ ] Test standard IPv4 addresses (192.168.1.1)
135
- - [ ] Test IPv6 addresses (standard and compressed)
136
- - [ ] Test edge cases (0.0.0.0, 255.255.255.255, ::1)
137
- - [ ] Test invalid formats
138
-
139
- ### Registration:
140
- - [ ] Add requires to `lib/hash_validator/validators.rb`
141
-
142
- **Implementation Notes:**
143
- <!-- Add discoveries and changes here during implementation -->
144
-
145
- ---
146
-
147
- ## Phase 3: Parameterized Validators - Length
148
- **Status:** [ ] Not Started | [ ] In Progress | [ ] Completed
149
- **Validators:** Length with min/max/exactly options
150
-
151
- ### Tasks:
152
- - [ ] Create Length validation class (`lib/hash_validator/validations/length.rb`)
153
- - Similar structure to `Optional`, `Many`, `Multiple` classes
154
- - Store min, max, exactly options
155
-
156
- - [ ] Create Length validator (`lib/hash_validator/validators/length_validator.rb`)
157
- - Handle strings, arrays, hashes
158
- - Support options: `min`, `max`, `exactly`
159
- - Dynamic error messages based on constraints
160
-
161
- - [ ] Add factory method to `lib/hash_validator.rb`:
162
- ```ruby
163
- def self.length(options)
164
- Validations::Length.new(options)
165
- end
166
- ```
167
-
168
- ### Usage Examples:
169
- ```ruby
170
- HashValidator.length(min: 5, max: 10)
171
- HashValidator.length(exactly: 8)
172
- HashValidator.length(min: 5)
173
- ```
174
-
175
- ### Tests:
176
- - [ ] Test all option combinations
177
- - [ ] Test with strings, arrays, hashes
178
- - [ ] Test boundary conditions
179
- - [ ] Test invalid option combinations
180
-
181
- **Implementation Notes:**
182
- <!-- Add discoveries and changes here during implementation -->
183
-
184
- ---
185
-
186
- ## Phase 4: Parameterized Validators - Numeric Ranges
187
- **Status:** [ ] Not Started | [ ] In Progress | [ ] Completed
188
- **Validators:** Between, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual
189
-
190
- ### Tasks:
191
- - [ ] Create Range validation classes in `lib/hash_validator/validations/`:
192
- - `between.rb` - Between two values (inclusive)
193
- - `greater_than.rb` - Greater than value
194
- - `less_than.rb` - Less than value
195
- - `greater_than_or_equal.rb` - Greater than or equal
196
- - `less_than_or_equal.rb` - Less than or equal
197
-
198
- - [ ] Create corresponding validators in `lib/hash_validator/validators/`
199
-
200
- - [ ] Add factory methods to `lib/hash_validator.rb`:
201
- ```ruby
202
- def self.between(min, max)
203
- Validations::Between.new(min, max)
204
- end
205
-
206
- def self.greater_than(value)
207
- Validations::GreaterThan.new(value)
208
- end
209
- # ... etc
210
- ```
211
-
212
- ### Usage Examples:
213
- ```ruby
214
- HashValidator.between(1, 100)
215
- HashValidator.greater_than(0)
216
- HashValidator.less_than_or_equal(100)
217
- ```
218
-
219
- ### Tests:
220
- - [ ] Test numeric types (Integer, Float, Rational)
221
- - [ ] Test boundary values
222
- - [ ] Test with non-numeric types
223
- - [ ] Test with nil
224
-
225
- **Implementation Notes:**
226
- <!-- Add discoveries and changes here during implementation -->
227
-
228
- ---
229
-
230
- ## Phase 5: Documentation and Final Testing
231
- **Status:** [ ] Not Started | [ ] In Progress | [ ] Completed
232
-
233
- ### Tasks:
234
- - [ ] Update README.md with all new validators
235
- - Add to simple types list
236
- - Add to "Additional validations" section
237
- - Provide usage examples for each
238
-
239
- - [ ] Update CLAUDE.md if needed
240
-
241
- - [ ] Run full test suite
242
-
243
- - [ ] Check for any performance impacts
244
-
245
- - [ ] Verify backward compatibility
246
-
247
- ### Documentation Sections to Update:
248
- - [ ] Usage section - add new simple validators
249
- - [ ] Additional validations - add parameterized validators
250
- - [ ] Examples section - comprehensive examples
251
-
252
- **Implementation Notes:**
253
- <!-- Add discoveries and changes here during implementation -->
254
-
255
- ---
256
-
257
- ## Quality Checklist (Run after each phase)
258
- - [ ] All new tests pass
259
- - [ ] All existing tests still pass
260
- - [ ] No rubocop/style violations (if configured)
261
- - [ ] Documentation is updated
262
- - [ ] Code follows existing patterns
263
-
264
- ## Technical Decisions & Rationale
265
-
266
- ### Pattern Consistency
267
- All validators follow the existing pattern:
268
- 1. Inherit from `HashValidator::Validator::Base`
269
- 2. Initialize with validator name
270
- 3. Implement `validate` method
271
- 4. Auto-register using `HashValidator.append_validator`
272
-
273
- ### Error Message Style
274
- Consistent with existing validators:
275
- - Simple validators: "is not a valid [type]"
276
- - Constraint validators: "must be [constraint]"
277
- - Type validators: "[type] required"
278
-
279
- ### Validation Approach
280
- - **URL**: Use Ruby's built-in `URI.parse` for robustness
281
- - **IP Addresses**: Regex for IPv4, consider `IPAddr` for IPv6
282
- - **JSON**: Use `JSON.parse` with exception handling
283
- - **Patterns**: Simple regex patterns for performance
284
-
285
- ### File Organization
286
- - Simple validators: `lib/hash_validator/validators/[name]_validator.rb`
287
- - Parameterized validations: `lib/hash_validator/validations/[name].rb`
288
- - Tests mirror structure: `spec/validators/[name]_spec.rb`
289
-
290
- ## Notes for Future Sessions
291
- When resuming work on this plan:
292
- 1. Check this document's status indicators
293
- 2. Review Implementation Notes for each completed phase
294
- 3. Run test suite to verify current state
295
- 4. Continue from the next uncompleted task
296
-
297
- ## Completion Criteria
298
- - [x] Phase 1: All 6 string pattern validators implemented and tested
299
- - [ ] Phase 2: All 3 IP address validators implemented and tested
300
- - [ ] Phase 3: Length validator implemented and tested
301
- - [ ] Phase 4: All 5 numeric range validators implemented and tested
302
- - [x] README fully updated with new validators and Rails integration
303
- - [x] All tests passing (451/451)
304
- - [x] Rails ActionController::Parameters support added
305
- - [x] Ruby 3.0+ minimum version requirement updated
306
- - [ ] Gem builds successfully
307
- - [ ] Version bump considered
308
-
309
- **Progress: Phase 1 Complete (6/11 validators) + Major Rails Integration Enhancement**