Class: Strict::Methods::VerifiableMethod

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/strict/methods/verifiable_method.rb

Overview

rubocop:disable Metrics/ClassLength

Defined Under Namespace

Classes: UnknownParameterError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(method:, parameters:, returns:, instance:) ⇒ VerifiableMethod

Returns a new instance of VerifiableMethod.



31
32
33
34
35
36
37
# File 'lib/strict/methods/verifiable_method.rb', line 31

def initialize(method:, parameters:, returns:, instance:)
  @method = method
  @parameters = parameters
  @parameters_index = parameters.to_h { |p| [p.name, p] }
  @returns = returns
  @instance = instance
end

Instance Attribute Details

#parametersObject (readonly)

Returns the value of attribute parameters.



29
30
31
# File 'lib/strict/methods/verifiable_method.rb', line 29

def parameters
  @parameters
end

#returnsObject (readonly)

Returns the value of attribute returns.



29
30
31
# File 'lib/strict/methods/verifiable_method.rb', line 29

def returns
  @returns
end

Instance Method Details

#to_sObject



39
40
41
# File 'lib/strict/methods/verifiable_method.rb', line 39

def to_s
  "#{method.owner}#{separator}#{name}"
end

#verify_definition!Object



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/strict/methods/verifiable_method.rb', line 43

def verify_definition!
  expected_parameters = Set.new(parameters.map(&:name))
  defined_parameters = Set.new(method.parameters.filter_map { |kind, name| name unless kind == :block })
  return if expected_parameters == defined_parameters

  missing_parameters = expected_parameters - defined_parameters
  additional_parameters = defined_parameters - expected_parameters
  raise Strict::MethodDefinitionError.new(
    verifiable_method: self,
    missing_parameters: missing_parameters,
    additional_parameters: additional_parameters
  )
end

#verify_parameters!(*args, **kwargs) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/BlockLength TODO(kkt): clean this up- it’s late, though, and the tests are passing



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/strict/methods/verifiable_method.rb', line 59

def verify_parameters!(*args, **kwargs)
  invalid_parameters = nil
  missing_parameters = nil

  positional_arguments = []
  keyword_arguments = {}

  # TODO(kkt): doesn't handle oddly sorted optional positional parameters like def foo(opt = nil, req)
  method.parameters.each do |kind, name|
    case kind
    when POSITIONAL
      parameter_kind = :positional
      value = args.any? ? args.shift : NOT_PROVIDED
    when REST
      parameter_kind = :rest
      value = [*args]
      args.clear
    when KEYWORD
      parameter_kind = :keyword
      value = kwargs.key?(name) ? kwargs.delete(name) : NOT_PROVIDED
    when KEYREST
      parameter_kind = :keyrest
      value = { **kwargs }
      kwargs.clear
    end
    next unless parameter_kind

    parameter = parameter_named!(name)
    if value.equal?(NOT_PROVIDED) && parameter.optional?
      value = parameter.default_generator.call
    elsif value.equal?(NOT_PROVIDED)
      missing_parameters ||= []
      missing_parameters << parameter.name
      next
    end

    value = parameter.coerce(value)
    if parameter.valid?(value)
      case parameter_kind
      when :positional
        positional_arguments << value
      when :rest
        positional_arguments.concat(value)
      when :keyword
        keyword_arguments[name] = value
      when :keyrest
        keyword_arguments.merge!(value)
      end
    else
      invalid_parameters ||= {}
      invalid_parameters[parameter] = value
    end
  end

  if args.empty? && kwargs.empty? && invalid_parameters.nil? && missing_parameters.nil?
    [positional_arguments, keyword_arguments]
  else
    raise Strict::MethodCallError.new(
      verifiable_method: self,
      remaining_args: args,
      remaining_kwargs: kwargs,
      invalid_parameters: invalid_parameters,
      missing_parameters: missing_parameters
    )
  end
end

#verify_returns!(value) ⇒ Object

rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/BlockLength



127
128
129
130
131
132
# File 'lib/strict/methods/verifiable_method.rb', line 127

def verify_returns!(value)
  value = returns.coerce(value)
  return if returns.valid?(value)

  raise Strict::MethodReturnError.new(verifiable_method: self, value: value)
end