Class: Highway::Steps::Parameters::Compound

Inherits:
Base
  • Object
show all
Defined in:
lib/highway/steps/parameters/compound.rb

Overview

This class is used in step definition classes to represent a compound parameter of a step that consists of other parameters.

Instance Attribute Summary collapse

Attributes inherited from Base

#name

Instance Method Summary collapse

Methods inherited from Base

#is_required?

Constructor Details

#initialize(name:, required:, defaults: false, children:) ⇒ Compound

Initialize an instance.

Parameters:

  • name (String)

    Name of the parameter.

  • required (Boolean)

    Whether parametr is required.

  • defaults (Boolean) (defaults to: false)

    Whether to construct default value from child parameters.

  • children (Array<Highway::Steps::Parameters::*>)

    Child parameters.



22
23
24
25
26
27
# File 'lib/highway/steps/parameters/compound.rb', line 22

def initialize(name:, required:, defaults: false, children:)
  @name = name
  @required = required
  @defaults = defaults
  @children = children
end

Instance Attribute Details

#childrenArray<Highway::Steps::Parameters::*> (readonly)

Child parameters.

Returns:



32
33
34
# File 'lib/highway/steps/parameters/compound.rb', line 32

def children
  @children
end

Instance Method Details

#defaultHash?

Default value of the parameter.

Returns:

  • (Hash, nil)


46
47
48
49
50
# File 'lib/highway/steps/parameters/compound.rb', line 46

def default
  if @defaults
    Utilities::hash_map(@children) { |child| [child.name, child.default] }
  end
end

#find_child_for_name(name) ⇒ Highway::Steps::Parameters::*

Find a child parameter definition by name.

Parameters:

  • name (String)

    Name of the parameter

Returns:



39
40
41
# File 'lib/highway/steps/parameters/compound.rb', line 39

def find_child_for_name(name)
  @children.find { |child| child.name == name }
end

#typecheck_and_prevalidate(values, interface:, keypath: []) ⇒ Void

Typecheck and prevalidate a value of the parameter. This method is used during the initial prevalidation of step parameter values before evaluating all the values.

This method works in a similar way to ‘typecheck_and_validate` with one difference: if it encounters a single parameter whose value is (or contains) `:ignore` symbol, it doesn’t perform any typechecking and validation on it. That way, the caller can specify which values should be fully validated and which should be ignored.

Parameters:

  • value (Object)

    A value.

  • interface (Highway::Interface)

    An interface instance.

  • keypath (Array<String>) (defaults to: [])

    A keypath to be used for debugging purposes.

Returns:

  • (Void)


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/highway/steps/parameters/compound.rb', line 106

def typecheck_and_prevalidate(values, interface:, keypath: [])

  unless values.is_a?(Hash)
    interface.fatal!("Invalid type of value for parameter: '#{Utilities::keypath_to_s(keypath)}'.")
  end

  @children.each { |child|
    if child.is_required? && !values.keys.include?(child.name) && child.default == nil
      interface.fatal!("Missing value for required parameter: '#{Utilities::keypath_to_s(keypath + [child.name])}'.")
    end
  }

  values.keys.each { |name|
    unless find_child_for_name(name)
      expected = @children.map { |child| "'#{child.name}'" }.join(", ")
      interface.fatal!("Unknown parameter: '#{Utilities::keypath_to_s(keypath + [name])}'. Expected one of: [#{expected}].")
    end
  }

  values.each_pair { |name, value|
    if (child = find_child_for_name(name))
      if child.is_a?(Parameters::Compound)
        child.typecheck_and_prevalidate(value, interface: interface, keypath: keypath + [name])
      elsif !Utilities::recursive_include?(value, :ignore)
        child.typecheck_and_validate(value, interface: interface, keypath: keypath + [name])
      end
    end
  }

end

#typecheck_and_validate(values, interface:, keypath: []) ⇒ Object

Typecheck and validate a value of the parameter.

This method returns typechecked, coerced and validated value or raises a fatal error if value has invalid type, can’t be coerced or is othweriwse invalid.

Parameters:

  • value (Object)

    A value.

  • interface (Highway::Interface)

    An interface instance.

  • keypath (Array<String>) (defaults to: [])

    A keypath to be used for debugging purposes.

Returns:

  • (Object)


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
# File 'lib/highway/steps/parameters/compound.rb', line 63

def typecheck_and_validate(values, interface:, keypath: [])

  unless values.is_a?(Hash)
    interface.fatal!("Invalid type of value for parameter: '#{Utilities::keypath_to_s(keypath)}'.")
  end

  @children.each { |child|
    if child.is_required? && !values.keys.include?(child.name) && child.default == nil
      interface.fatal!("Missing value for required parameter: '#{Utilities::keypath_to_s(keypath + [child.name])}'.")
    end
  }

  values.keys.each { |name|
    unless find_child_for_name(name)
      expected = @children.map { |child| "'#{child.name}'" }.join(", ")
      interface.fatal!("Unknown parameter: '#{Utilities::keypath_to_s(keypath + [name])}'. Expected one of: [#{expected}].")
    end
  }

  typechecked = Utilities::hash_map(values) { |name, value|
    child = find_child_for_name(name)
    [name, child.typecheck_and_validate(value, interface: interface, keypath: keypath + [name])]
  }

  (default || {}).merge(typechecked)

end