method_argument_constraints 0.1.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 +7 -0
- data/lib/method_argument_constraints.rb +83 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 811e1791560b4fa12bb4beacde28f07a7e93bb0a9d7e9f82bd8af7046bf84f7b
|
4
|
+
data.tar.gz: f0e2d9dc9fda5b1ae35fe162d37a0e8491a78c01055a85a9ba5373c595b24dd0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 136425ad0dfaf09afb89a631da1e086973cf3c6f4efc050aaffec5a3a20ec97f5335a8fdb6679c64cec96f3eef92e66ddf744af516d72dad01e16ed759c95020
|
7
|
+
data.tar.gz: 83556167a7132b14ea9c38ae7abb848ad0a08a578e284bebdff43adc2d789bf31d8eb4c4606096565ffecbbbb786fabd08992450e456fe871d431c7d2602e647
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module MethodArgumentConstraints
|
2
|
+
class RequirementsFailed < StandardError; end
|
3
|
+
class WrongDataTypeError < StandardError; end
|
4
|
+
class NoBindingError < StandardError; end
|
5
|
+
|
6
|
+
def method_constraints!(caller_binding, params)
|
7
|
+
raise NoBindingError.new("No binding passed for method using method_constraints!") unless caller_binding.is_a? Binding
|
8
|
+
caller_method = caller_locations(1,1).first.label
|
9
|
+
arguments = _method_attributes(caller_binding, caller_method, params)
|
10
|
+
evaluations = []
|
11
|
+
arguments.each do |param_name, param_details|
|
12
|
+
evaluations << _validate_param(param_name, param_details)
|
13
|
+
end
|
14
|
+
evaluations.compact!
|
15
|
+
return if evaluations.empty?
|
16
|
+
raise RequirementsFailed.new(_build_failure_error(evaluations))
|
17
|
+
end
|
18
|
+
|
19
|
+
private def _build_failure_error(evaluations)
|
20
|
+
evaluations_formatted = evaluations.inject("") do |final_string, evaluation|
|
21
|
+
"#{final_string} #{evaluation.class}: #{evaluation.message}\n"
|
22
|
+
end
|
23
|
+
"Requirements failed with the following errors: \n#{evaluations_formatted}"
|
24
|
+
end
|
25
|
+
|
26
|
+
private def _validate_param(param_name, param_details)
|
27
|
+
param_value = param_details[:value]
|
28
|
+
param_constraint = param_details[:constraint]
|
29
|
+
if param_details[:required]
|
30
|
+
return if param_constraint.nil?
|
31
|
+
unless _requirement_passed?(param_value, param_constraint, param_name)
|
32
|
+
_build_required_param_error(param_name, param_constraint)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
return if param_value.nil? || param_constraint.nil?
|
36
|
+
unless _requirement_passed?(param_value, param_constraint, param_name)
|
37
|
+
_optional_param_error(param_name, param_constraint)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private def _requirement_passed?(param_value, param_constraint, param_name)
|
43
|
+
if param_constraint.is_a? Proc
|
44
|
+
param_constraint.call(param_value, param_name)
|
45
|
+
elsif param_constraint.is_a? Symbol
|
46
|
+
public_send(param_constraint, param_value, param_name)
|
47
|
+
else
|
48
|
+
param_value.is_a?(param_constraint)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private def _build_required_param_error(param_name, param_constraint)
|
53
|
+
if param_constraint.is_a?(Proc) || param_constraint.is_a?(Symbol)
|
54
|
+
message = "#{param_name} failed required validation it does not meet set constraint"
|
55
|
+
else
|
56
|
+
message = "#{param_name} failed required validation as it is not off type #{param_constraint}"
|
57
|
+
end
|
58
|
+
WrongDataTypeError.new(message)
|
59
|
+
end
|
60
|
+
|
61
|
+
private def _optional_param_error(param_name, param_constraint)
|
62
|
+
if param_constraint.is_a?(Proc) || param_constraint.is_a?(Symbol)
|
63
|
+
message = "#{param_name} failed required validation it does not meet set constraint"
|
64
|
+
else
|
65
|
+
message = "#{param_name} failed optional param validation as it is not off type #{param_constraint} or set to nil"
|
66
|
+
end
|
67
|
+
WrongDataTypeError.new(message)
|
68
|
+
end
|
69
|
+
|
70
|
+
private def _method_attributes(method_binding, method_name, constraints)
|
71
|
+
method(method_name).parameters.each_with_object({}) do |parameter, attributes|
|
72
|
+
required_or_optional = parameter.first
|
73
|
+
name = parameter.last
|
74
|
+
attributes[name] = {
|
75
|
+
required: (required_or_optional == :req),
|
76
|
+
value: method_binding.local_variable_get(name),
|
77
|
+
constraint: constraints.dig(name)
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
Object.include MethodArgumentConstraints
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: method_argument_constraints
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh Etsenake
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Call method_contraints! with the param name and constraint to enforce
|
14
|
+
validation on it
|
15
|
+
email:
|
16
|
+
- etsenake@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/method_argument_constraints.rb
|
22
|
+
homepage:
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata:
|
26
|
+
allowed_push_host: https://rubygems.org
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubygems_version: 3.1.2
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Asserts argument constraints on method arguments
|
46
|
+
test_files: []
|