lib/lucid/interface.rb in lucid-0.3.3 vs lib/lucid/interface.rb in lucid-0.4.0
- old
+ new
@@ -1,8 +1,129 @@
+require 'lucid/step_match'
+require 'lucid/step_definition_usage'
+
module Lucid
# This module defines the API for programming language support in Lucid.
# While Lucid itself is written in Ruby, any programming language can
# be supported by implementing this API. Each language implementation
# must manage its own events and must execute them at appropriate times.
module Interface
+ module InterfaceMethods
+ def around(scenario)
+ execute_around(scenario) do
+ yield
+ end
+ end
+
+ def before(scenario)
+ begin_scenario(scenario)
+ execute_before(scenario)
+ end
+
+ def after(scenario)
+ execute_after(scenario)
+ end_scenario
+ end
+
+ def after_configuration(configuration)
+ hooks[:after_configuration].each do |hook|
+ hook.invoke('AfterConfiguration', configuration)
+ end
+ end
+
+ def execute_after_step(scenario)
+ hooks_for(:after_step, scenario).each do |hook|
+ invoke(hook, 'AfterStep', scenario, false)
+ end
+ end
+
+ def execute_transforms(args)
+ args.map do |arg|
+ matching_transform = transforms.detect {|transform| transform.match(arg) }
+ matching_transform ? matching_transform.invoke(arg) : arg
+ end
+ end
+
+ def add_hook(phase, hook)
+ hooks[phase.to_sym] << hook
+ hook
+ end
+
+ def clear_hooks
+ @hooks = nil
+ end
+
+ def add_transform(transform)
+ transforms.unshift transform
+ transform
+ end
+
+ def hooks_for(phase, scenario) #:nodoc:
+ hooks[phase.to_sym].select{|hook| scenario.accept_hook?(hook)}
+ end
+
+ def unmatched_step_definitions
+ available_step_definition_hash.keys - invoked_step_definition_hash.keys
+ end
+
+ def available_step_definition(regexp_source, file_colon_line)
+ available_step_definition_hash[StepDefinitionUsage.new(regexp_source, file_colon_line)] = nil
+ end
+
+ def invoked_step_definition(regexp_source, file_colon_line)
+ invoked_step_definition_hash[StepDefinitionUsage.new(regexp_source, file_colon_line)] = nil
+ end
+
+ private
+
+ def available_step_definition_hash
+ @available_step_definition_hash ||= {}
+ end
+
+ def invoked_step_definition_hash
+ @invoked_step_definition_hash ||= {}
+ end
+
+ def hooks
+ @hooks ||= Hash.new{|h,k| h[k] = []}
+ end
+
+ def transforms
+ @transforms ||= []
+ end
+
+ def execute_around(scenario, &block)
+ hooks_for(:around, scenario).reverse.inject(block) do |blk, hook|
+ proc do
+ invoke(hook, 'Around', scenario, true) do
+ blk.call(scenario)
+ end
+ end
+ end.call
+ end
+
+ def execute_before(scenario)
+ hooks_for(:before, scenario).each do |hook|
+ invoke(hook, 'Before', scenario, true)
+ end
+ end
+
+ def execute_after(scenario)
+ hooks_for(:after, scenario).reverse_each do |hook|
+ invoke(hook, 'After', scenario, true)
+ end
+ end
+
+ def invoke(hook, location, scenario, exception_fails_scenario, &block)
+ begin
+ hook.invoke(location, scenario, &block)
+ rescue Exception => exception
+ if exception_fails_scenario
+ scenario.fail!(exception)
+ else
+ raise
+ end
+ end
+ end
+ end
end
end