require 'cucumber/step_match' require 'cucumber/core_ext/string' require 'cucumber/core_ext/proc' module Cucumber module StepDefinitionMethods def step_match(name_to_match, name_to_report) if(match = name_to_match.match(regexp)) StepMatch.new(self, name_to_match, name_to_report, match.captures) else nil end end # Formats the matched arguments of the associated Step. This method # is usually called from visitors, which render output. # # The +format+ can either be a String or a Proc. # # If it is a String it should be a format string according to # Kernel#sprinf, for example: # # '%s' # # If it is a Proc, it should take one argument and return the formatted # argument, for example: # # lambda { |param| "[#{param}]" } # def format_args(step_name, format) step_name.gzub(regexp, format) end def match(step_name) case step_name when String then regexp.match(step_name) when Regexp then regexp == step_name end end def backtrace_line "#{file_colon_line}:in `#{regexp.inspect}'" end def text_length regexp.inspect.jlength end end # A Step Definition holds a Regexp and a Proc, and is created # by calling Given, When or Then # in the step_definitions ruby files - for example: # # Given /I have (\d+) cucumbers in my belly/ do # # some code here # end # class StepDefinition def self.snippet_text(step_keyword, step_name) escaped = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/') param_pattern = /"([^\"]*)"/ match = escaped.match(param_pattern) if match n = 0 block_args = match.captures.map do |a| n += 1 "arg#{n}" end block_arg_string = " |#{block_args.join(", ")}|" else block_arg_string = "" end escaped = escaped.gsub(param_pattern, '"([^\\"]*)"') "#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n pending\nend" end class MissingProc < StandardError def message "Step definitions must always have a proc" end end include StepDefinitionMethods def initialize(pattern, &proc) raise MissingProc if proc.nil? if String === pattern p = pattern.gsub(/\$\w+/, '(.*)') # Replace $var with (.*) pattern = Regexp.new("^#{p}$") end @regexp, @proc = pattern, proc end def regexp @regexp end def invoke(world, args) args = args.map{|arg| Ast::PyString === arg ? arg.to_s : arg} begin world.cucumber_instance_exec(true, regexp.inspect, *args, &@proc) rescue Cucumber::ArityMismatchError => e e.backtrace.unshift(self.backtrace_line) raise e end end def file_colon_line @proc.file_colon_line end end end