Module: Gemmy::Components::DynamicSteps

Defined in:
lib/gemmy/patches_loaded/components/dynamic_steps.rb

Overview

Mimics the Cucumber API:

{#step} runs a step
{#define_step} defines a step

The usage is the same as Cucumber:

define_step /I print (.+) (.+) times/ do |string, n|
  n.times { print string }
end

step "I print hello 2 times"
=> 'hellohello'

Like Cucumber, it will raise an error if there is > 1 matching step AmbiguousMatchError can be rescued if desired.

It also raises an error if no matcher was found

Defined Under Namespace

Classes: AmbiguousMatchError, NoMatchFoundError

Instance Method Summary collapse

Instance Method Details

#define_step(regex, &blk) ⇒ Object

Defines a regex => proc mapping A good pattern for regex is to use (.+) as match groups, and mirror those as sequential named parameters in the block.

Match groups are left-greedy, for example:

"1 2 3 4 5".match(/(.+) (.+)/).tap &:shift
# => ['1 2 3 4', '5']


46
47
48
# File 'lib/gemmy/patches_loaded/components/dynamic_steps.rb', line 46

def define_step(regex, &blk)
  steps[regex] = blk
end

#find_matching_steps(string) ⇒ Hash

Searches the keys in @steps for regexes that match the string.

Parameters:

  • string (String)

Returns:

  • (Hash)

    where keys are regexes and vals are hashes with signature: matches: [Array<String>] the String#match results proc: [Proc] the block mapped to the regex



80
81
82
83
84
85
86
87
88
# File 'lib/gemmy/patches_loaded/components/dynamic_steps.rb', line 80

def find_matching_steps(string)
  matching_steps = steps.reduce({}) do |matching_steps, (regex, proc)|
    match_results = string.match(regex).to_a.tap &:shift
    if match_results.any_not? &:blank?
      matching_steps[regex] = { matches: match_results, proc: proc }
    end
    matching_steps
  end
end

#step(string) ⇒ Object

run a step. searches @step keys for regex which matches the string then runs the associated proc, passing the regex match results



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/gemmy/patches_loaded/components/dynamic_steps.rb', line 54

def step(string)
  matching_steps = find_matching_steps(string)
  if matching_steps.keys.length > 1
    # Failure, multiple matching steps
    raise(
      AmbiguousMatchError,
      "step #{string} matched: #{matching_steps.keys.join(", ")}"
    )
  elsif matching_steps.keys.length == 0
    # Failure, no matching step
    raise(
      NoMatchFoundError,
      "step #{string} had no match"
    )
  else
    # Success, run the proc
    matching_step = matching_steps.values[0]
    matching_step[:proc].call(*(matching_step[:matches]))
  end
end

#stepsObject



34
35
36
# File 'lib/gemmy/patches_loaded/components/dynamic_steps.rb', line 34

def steps
  @steps ||= {}
end