validate-rb 1.0.0.alpha.1 → 1.0.0.alpha.2

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: b55536a2282b3141ff4111c11d5f08ad8f04f059e04a654a3cb7c05e60ee7a3d
4
- data.tar.gz: 9cc607cd83e595acc81097eb3919cdfcbd16d6fc4c79c15d9dd402c5baba18d1
3
+ metadata.gz: 6cbdd9ab7995b1b5affe50fce32d2f32fd3d49d12fc03484cbc934d312e4a15f
4
+ data.tar.gz: 593628eaacb2eed4d85d991fd0045395c82b43a28801b68801b065b62708b0f4
5
5
  SHA512:
6
- metadata.gz: ccd37c926676d904de86c3a1130e00c1f13fd36f7f1334e46965717dca0403af4c1986309deb4d81873cea505fcbf4aa0e61c79f0081de669cf4ed74775b5e69
7
- data.tar.gz: 1361c275de360acaf287edbd7e361b0ebf43572f487bd79224f37f888849efc3082a71c797883f9f6620699122732951f66dbcf2e4bc3b8470385e0d3385b4e4
6
+ metadata.gz: 38f7c973117e67ad6fe86fa0dcd2f2c5edce5263ab884f2153a679f00b453336668167992a16e540c03905fedf2b0710a8dc035bfcd88f26c31c687153d9900f
7
+ data.tar.gz: 74fd63f44829727fb8c5360b3a9675c5aefc7e61829d6441addf7430a86c42177974f327ac9468285de84e4b36220594eb54709ac1802b1295ca355078b33cdd
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'forwardable'
4
4
  require 'monitor'
5
+ require 'ipaddr'
5
6
 
6
7
  require_relative 'validate/version'
7
8
  require_relative 'validate/errors'
@@ -104,6 +104,40 @@ module Validate
104
104
  key { "length_over_#{options[:min]}_under_#{options[:max]}" }
105
105
  end
106
106
 
107
+ define(:bytesize, message: 'have byte length of %{constraint.describe_length}') do
108
+ option(:min) { respond_to(:>, message: 'min must respond to :>') }
109
+ option(:max) { respond_to(:<, message: 'max must respond to :<') }
110
+
111
+ initialize do |range = nil|
112
+ case range
113
+ when ::Range
114
+ { min: range.min, max: range.max }
115
+ else
116
+ { min: range, max: range }
117
+ end
118
+ end
119
+ evaluate do |value|
120
+ pass if value.nil?
121
+ fail unless value.respond_to?(:bytesize)
122
+
123
+ bytesize = value.bytesize
124
+ fail if (options[:min]&.> bytesize) || (options[:max]&.< bytesize)
125
+ end
126
+
127
+ def describe_length
128
+ if options[:max] == options[:min]
129
+ options[:max].to_s
130
+ elsif options[:max].nil?
131
+ "at least #{options[:min]}"
132
+ elsif options[:min].nil?
133
+ "at most #{options[:max]}"
134
+ else
135
+ "at least #{options[:min]} and at most #{options[:max]}"
136
+ end
137
+ end
138
+ key { "bytesize_over_#{options[:min]}_under_#{options[:max]}" }
139
+ end
140
+
107
141
  define(:one_of, message: 'be %{constraint.describe_presence}') do
108
142
  option(:values) do
109
143
  respond_to(:include?, message: 'values must respond to :include?')
@@ -309,6 +343,146 @@ module Validate
309
343
  end
310
344
  end
311
345
 
346
+ define(:each_key, message: 'have keys') do
347
+ option(:constraints) do
348
+ not_nil(message: 'constraints are required')
349
+ is_a(AST::DefinitionContext, message: 'constraints must be a DefinitionContext')
350
+ end
351
+
352
+ initialize do |&block|
353
+ return {} if block.nil?
354
+
355
+ { constraints: AST::DefinitionContext.create(&block) }
356
+ end
357
+ evaluate do |collection, ctx|
358
+ pass if collection.nil?
359
+ fail unless collection.respond_to?(:each_key)
360
+
361
+ constraints = options[:constraints]
362
+ collection.each_key do |key|
363
+ key_ctx = Constraints::ValidationContext.key(key)
364
+ constraints.evaluate(key_ctx)
365
+ ctx.merge(key_ctx) if key_ctx.has_violations?
366
+ end
367
+ end
368
+ end
369
+
370
+ define(:start_with, message: 'start with %{constraint.prefix}') do
371
+ option(:prefix) do
372
+ not_blank(message: 'prefix is required')
373
+ is_a(String, message: 'prefix must be a String')
374
+ end
375
+
376
+ initialize do |prefix = nil|
377
+ return {} if prefix.nil?
378
+
379
+ { prefix: prefix }
380
+ end
381
+ evaluate do |value|
382
+ pass if value.nil?
383
+ fail unless value.respond_to?(:start_with?) && value.start_with?(options[:prefix])
384
+ end
385
+ key do
386
+ "start_with_#{options[:prefix]}"
387
+ end
388
+ end
389
+
390
+ define(:end_with, message: 'end with %{constraint.suffix}') do
391
+ option(:suffix) do
392
+ not_blank(message: 'suffix is required')
393
+ is_a(String, message: 'suffix must be a String')
394
+ end
395
+
396
+ initialize do |suffix = nil|
397
+ return {} if suffix.nil?
398
+
399
+ { suffix: suffix }
400
+ end
401
+ evaluate do |value|
402
+ pass if value.nil?
403
+ fail unless value.respond_to?(:end_with?) && value.end_with?(options[:suffix])
404
+ end
405
+ key do
406
+ "end_with_#{options[:suffix]}"
407
+ end
408
+ end
409
+
410
+ define(:contain, message: 'contain %{constraint.substring}') do
411
+ option(:substring) do
412
+ not_blank(message: 'substring is required')
413
+ is_a(String, message: 'substring must be a String')
414
+ end
415
+
416
+ initialize do |substring = nil|
417
+ return {} if substring.nil?
418
+
419
+ { substring: substring }
420
+ end
421
+ evaluate do |value|
422
+ pass if value.nil?
423
+ fail unless value.respond_to?(:include?) && value.include?(options[:substring])
424
+ end
425
+ key do
426
+ "contain_#{options[:substring]}"
427
+ end
428
+ end
429
+
430
+ define(:uuid, message: 'be a uuid') do
431
+ UUID_REGEXP = %r{\b\h{8}\b-\h{4}-\h{4}-\h{4}-\b\h{12}\b}
432
+
433
+ evaluate do |value|
434
+ pass if value.nil?
435
+ fail unless UUID_REGEXP.match?(value.to_s)
436
+ end
437
+ end
438
+
439
+ define(:hostname, message: 'be a hostname') do
440
+ HOSTNAME_REGEXP = URI::HOST
441
+
442
+ evaluate do |value|
443
+ pass if value.nil?
444
+ fail unless HOSTNAME_REGEXP.match?(value.to_s)
445
+ end
446
+ end
447
+
448
+ define(:uri, message: 'be a uri') do
449
+ option(:absolute, default: true) do
450
+ one_of([true, false], message: ':absolute must be true or false')
451
+ end
452
+
453
+ evaluate do |value|
454
+ pass if value.nil?
455
+ uri = begin
456
+ URI.parse(value)
457
+ rescue URI::Error
458
+ fail
459
+ end
460
+ fail unless options[:absolute] == uri.absolute?
461
+ end
462
+ end
463
+
464
+ define(:ip_address, message: 'be an ip address') do
465
+ option(:version, default: nil) do
466
+ one_of([:v4, :v6], message: 'must be a valid ip version')
467
+ end
468
+
469
+ initialize do |version = nil|
470
+ return {} if version.nil?
471
+
472
+ { version: version }
473
+ end
474
+ evaluate do |value|
475
+ pass if value.nil?
476
+ addr = begin
477
+ IPAddr.new(value)
478
+ rescue IPAddr::Error
479
+ fail
480
+ end
481
+ version = options[:version]
482
+ fail unless version.nil? || addr.send(:"ip#{version}?")
483
+ end
484
+ end
485
+
312
486
  define(
313
487
  :unique,
314
488
  message: 'have unique %{constraint.describe_unique_attribute}'
@@ -11,7 +11,12 @@ module Validate
11
11
  new(value, Path.new, violations)
12
12
  end
13
13
 
14
- attr_reader :value
14
+ def self.key(key, violations = [])
15
+ new(key, Path.new([KeyPath.new(key)]), violations)
16
+ end
17
+
18
+ attr_reader :value, :violations
19
+ protected :violations
15
20
 
16
21
  def initialize(value, path = Path.new, violations = [])
17
22
  @value = value
@@ -65,6 +70,13 @@ module Validate
65
70
  Error::ConstraintViolationError.new(@violations.freeze)
66
71
  end
67
72
 
73
+ def merge(other)
74
+ other.violations.each do |violation|
75
+ @violations << Constraint::Violation.new(violation.value, @path.child(violation.path), violation.constraint)
76
+ end
77
+ self
78
+ end
79
+
68
80
  private
69
81
 
70
82
  def create_violation(constraint)
@@ -87,7 +99,12 @@ module Validate
87
99
  end
88
100
 
89
101
  def child(path)
90
- Path.new(@paths.dup << path)
102
+ case path
103
+ when KeyPath, AttrPath
104
+ Path.new(@paths.dup << path)
105
+ when Path
106
+ Path.new(@paths.dup << path.to_a)
107
+ end
91
108
  end
92
109
 
93
110
  def to_s
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Validate
4
- VERSION = '1.0.0.alpha.1'
4
+ VERSION = '1.0.0.alpha.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validate-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.1
4
+ version: 1.0.0.alpha.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bulat Shakirzyanov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-22 00:00:00.000000000 Z
11
+ date: 2020-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aruba