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.
@@ -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: []