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

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