Module: StateMachines::OptionsValidator

Defined in:
lib/state_machines/options_validator.rb

Overview

Define the module if it doesn’t exist yet Module for validating options without monkey-patching Hash Provides the same functionality as the Hash monkey patch but in a cleaner way

Class Method Summary collapse

Class Method Details

.assert_exclusive_keys!(options, *exclusive_keys, caller_info: nil) ⇒ Object

Validates that at most one of the exclusive keys is present in the options hash

Raises:

  • (ArgumentError)

    If more than one exclusive key is found



33
34
35
36
37
38
39
40
41
# File 'lib/state_machines/options_validator.rb', line 33

def assert_exclusive_keys!(options, *exclusive_keys, caller_info: nil)
  return if options.empty?

  conflicting_keys = exclusive_keys & options.keys
  return if conflicting_keys.length <= 1

  caller_context = caller_info ? " in #{caller_info}" : ''
  raise ArgumentError, "Conflicting keys: #{conflicting_keys.join(', ')}#{caller_context}"
end

.assert_valid_keys!(options, *valid_keys, caller_info: nil) ⇒ Object

Validates that all keys in the options hash are in the list of valid keys

Raises:

  • (ArgumentError)

    If any invalid keys are found



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/state_machines/options_validator.rb', line 15

def assert_valid_keys!(options, *valid_keys, caller_info: nil)
  return if options.empty?

  valid_keys.flatten!
  invalid_keys = options.keys - valid_keys

  return if invalid_keys.empty?

  caller_context = caller_info ? " in #{caller_info}" : ''
  raise ArgumentError, "Unknown key#{'s' if invalid_keys.length > 1}: #{invalid_keys.map(&:inspect).join(', ')}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}#{caller_context}"
end

.validate_and_return(options, *valid_keys) ⇒ Hash

Helper method for backwards compatibility - allows gradual migration from Hash monkey patch to this module



66
67
68
69
# File 'lib/state_machines/options_validator.rb', line 66

def validate_and_return(options, *valid_keys)
  assert_valid_keys!(options, *valid_keys)
  options
end

.validator(valid_keys: [], exclusive_key_groups: [], caller_info: nil) ⇒ Proc

Validates options using a more convenient interface that works with both hash-style and kwargs-style method definitions



50
51
52
53
54
55
56
57
58
# File 'lib/state_machines/options_validator.rb', line 50

def validator(valid_keys: [], exclusive_key_groups: [], caller_info: nil)
  proc do |options|
    assert_valid_keys!(options, *valid_keys, caller_info: caller_info) unless valid_keys.empty?

    exclusive_key_groups.each do |group|
      assert_exclusive_keys!(options, *group, caller_info: caller_info)
    end
  end
end