Skip to content

Commit

Permalink
Refactor, removing more methods from the Runtime class and putting th…
Browse files Browse the repository at this point in the history
…em into a delegator object (Runtime::ForProgrammingLanguages) that faces the programming languages.

Now much easier to see the dependency from Programming Language -> Runtime / Support Code
  • Loading branch information
mattwynne committed Oct 3, 2010
1 parent c43d701 commit fda9f05
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 70 deletions.
61 changes: 0 additions & 61 deletions lib/cucumber/runtime.rb
Expand Up @@ -48,67 +48,6 @@ def steps(status = nil)
@results.steps(status)
end

# Loads and registers programming language implementation.
# Instances are cached, so calling with the same argument
# twice will return the same instance.
#
def load_programming_language(ext)
@support_code.load_programming_language!(ext)
end

def invoke(step_name, multiline_argument=nil)
# It is very important to leave multiline_argument=nil as a vararg. Cuke4Duke needs it that way.
@support_code.invoke(step_name, multiline_argument)
end

# Invokes a series of steps +steps_text+. Example:
#
# invoke(%Q{
# Given I have 8 cukes in my belly
# Then I should not be thirsty
# })
def invoke_steps(steps_text, i18n, file_colon_line)
@support_code.invoke_steps(steps_text, i18n, file_colon_line)
end

# Returns a Cucumber::Ast::Table for +text_or_table+, which can either
# be a String:
#
# table(%{
# | account | description | amount |
# | INT-100 | Taxi | 114 |
# | CUC-101 | Peeler | 22 |
# })
#
# or a 2D Array:
#
# table([
# %w{ account description amount },
# %w{ INT-100 Taxi 114 },
# %w{ CUC-101 Peeler 22 }
# ])
#
def table(text_or_table, file=nil, line_offset=0)
if Array === text_or_table
Ast::Table.new(text_or_table)
else
Ast::Table.parse(text_or_table, file, line_offset)
end
end

# Returns a regular String for +string_with_triple_quotes+. Example:
#
# """
# hello
# world
# """
#
# Is retured as: " hello\nworld"
#
def py_string(string_with_triple_quotes, file=nil, line_offset=0)
Ast::PyString.parse(string_with_triple_quotes)
end

def step_match(step_name, name_to_report=nil) #:nodoc:
@support_code.step_match(step_name, name_to_report)
end
Expand Down
65 changes: 65 additions & 0 deletions lib/cucumber/runtime/for_programming_languages.rb
@@ -0,0 +1,65 @@
require 'forwardable'

module Cucumber
class Runtime
# This is what a programming language will consider to be a runtime.
#
# It's a thin class that directs the handul of methods needed by the
# programming languages to the right place.
class ForProgrammingLanguages
extend Forwardable

def initialize(support_code, runtime)
@support_code, @runtime = support_code, runtime
end

def_delegators :@runtime,
:embed,
:ask,
:announce

def_delegators :@support_code,
:invoke_steps,
:invoke,
:load_programming_language

# Returns a Cucumber::Ast::Table for +text_or_table+, which can either
# be a String:
#
# table(%{
# | account | description | amount |
# | INT-100 | Taxi | 114 |
# | CUC-101 | Peeler | 22 |
# })
#
# or a 2D Array:
#
# table([
# %w{ account description amount },
# %w{ INT-100 Taxi 114 },
# %w{ CUC-101 Peeler 22 }
# ])
#
def table(text_or_table, file=nil, line_offset=0)
if Array === text_or_table
Ast::Table.new(text_or_table)
else
Ast::Table.parse(text_or_table, file, line_offset)
end
end

# Returns a regular String for +string_with_triple_quotes+. Example:
#
# """
# hello
# world
# """
#
# Is retured as: " hello\nworld"
#
def py_string(string_with_triple_quotes, file=nil, line_offset=0)
Ast::PyString.parse(string_with_triple_quotes)
end
end
end
end
32 changes: 23 additions & 9 deletions lib/cucumber/runtime/support_code.rb
@@ -1,9 +1,12 @@
require 'cucumber/constantize'
require 'cucumber/runtime/for_programming_languages'

module Cucumber
class Runtime

class SupportCode

require 'forwardable'
class StepInvoker
include Gherkin::Rubify

Expand Down Expand Up @@ -31,25 +34,35 @@ def eof
end

include Constantize

def initialize(step_mother, in_guess_mode)
@step_mother = step_mother
def initialize(runtime, in_guess_mode)
@runtime_facade = Runtime::ForProgrammingLanguages.new(self, runtime)
@guess_step_matches = in_guess_mode
@unsupported_programming_languages = []
@programming_languages = []
@language_map = {}
end

# Invokes a series of steps +steps_text+. Example:
#
# invoke(%Q{
# Given I have 8 cukes in my belly
# Then I should not be thirsty
# })
def invoke_steps(steps_text, i18n, file_colon_line)
file, line = file_colon_line.split(':')
parser = Gherkin::Parser::Parser.new(StepInvoker.new(self), true, 'steps')
parser.parse(steps_text, file, line.to_i)
end

def load_programming_language!(ext)

# Loads and registers programming language implementation.
# Instances are cached, so calling with the same argument
# twice will return the same instance.
#
def load_programming_language(ext)
return @language_map[ext] if @language_map[ext]
programming_language_class = constantize("Cucumber::#{ext.capitalize}Support::#{ext.capitalize}Language")
programming_language = programming_language_class.new(@step_mother)
programming_language = programming_language_class.new(@runtime_facade)
@programming_languages << programming_language
@language_map[ext] = programming_language
programming_language
Expand All @@ -75,7 +88,7 @@ def unmatched_step_definitions
end

def snippet_text(step_keyword, step_name, multiline_arg_class) #:nodoc:
load_programming_language!('rb') if unknown_programming_language?
load_programming_language('rb') if unknown_programming_language?
@programming_languages.map do |programming_language|
programming_language.snippet_text(step_keyword, step_name, multiline_arg_class)
end.join("\n")
Expand Down Expand Up @@ -116,6 +129,7 @@ def step_match(step_name, name_to_report=nil) #:nodoc:
end

def invoke(step_name, multiline_argument=nil)
# It is very important to leave multiline_argument=nil as a vararg. Cuke4Duke needs it that way.
begin
step_match(step_name).invoke(multiline_argument)
rescue Exception => e
Expand Down Expand Up @@ -165,11 +179,11 @@ def log
Cucumber.logger
end

def programming_language_for(step_def_file) #:nodoc:
def programming_language_for(step_def_file)
if ext = File.extname(step_def_file)[1..-1]
return nil if @unsupported_programming_languages.index(ext)
begin
load_programming_language!(ext)
load_programming_language(ext)
rescue LoadError => e
log.debug("Failed to load '#{ext}' programming language for file #{step_def_file}: #{e.message}\n")
@unsupported_programming_languages << ext
Expand Down
4 changes: 4 additions & 0 deletions lib/cucumber/step_mother.rb
Expand Up @@ -6,5 +6,9 @@ def initialize(*args)
warn("StepMother has been deprecated and will be gently put to sleep before the next release. Please use Runtime instead. #{caller[0]}")
super
end

def load_programming_language(_)
# keeps spork happy
end
end
end

0 comments on commit fda9f05

Please sign in to comment.