lib/lopata/scenario_builder.rb in lopata-0.1.1 vs lib/lopata/scenario_builder.rb in lopata-0.1.2

- old
+ new

@@ -1,7 +1,8 @@ class Lopata::ScenarioBuilder attr_reader :title, :common_metadata + attr_accessor :shared_step, :group def self.define(title, metadata = {}, &block) builder = new(title, metadata) builder.instance_exec &block builder.build @@ -10,22 +11,22 @@ def initialize(title, metadata = {}) @title, @common_metadata = title, metadata end def build + filters = Lopata::Config.filters option_combinations.each do |option_set| metadata = common_metadata.merge(option_set.metadata) - scenario = Lopata::Scenario.new(title, option_set.title, metadata) + scenario = Lopata::Scenario::Execution.new(title, option_set.title, metadata) - steps.each do |step| - next if step.condition && !step.condition.match?(scenario) - step.pre_steps(scenario).each { |s| scenario.steps << s } - scenario.steps << step + unless filters.empty? + next unless filters.all? { |f| f[scenario] } end - if Lopata::Config.after_scenario - scenario.steps << Lopata::Step.new(:after_scenario, &Lopata::Config.after_scenario) + steps_with_hooks.each do |step| + next if step.condition && !step.condition.match?(scenario) + step.execution_steps(scenario).each { |s| scenario.steps << s } end world.scenarios << scenario end end @@ -56,32 +57,53 @@ def skip?(option_set) @skip_when && @skip_when.call(option_set) end - %i{ setup action it teardown }.each do |name| + %i{ setup action it teardown verify context }.each do |name| name_if = "%s_if" % name name_unless = "%s_unless" % name - define_method name, ->(*args, &block) { add_step(name, *args, &block) } - define_method name_if, ->(condition, *args, &block) { add_step(name, *args, condition: Lopata::Condition.new(condition), &block) } - define_method name_unless, ->(condition, *args, &block) { add_step(name, *args, condition: Lopata::Condition.new(condition, positive: false), &block) } + define_method name, ->(*args, **metadata, &block) { add_step(name, *args, metadata: metadata, &block) } + define_method name_if, ->(condition, *args, **metadata, &block) { + add_step(name, *args, metadata: metadata, condition: Lopata::Condition.new(condition), &block) + } + define_method name_unless, ->(condition, *args, **metadata, &block) { + add_step(name, *args, condition: Lopata::Condition.new(condition, positive: false), metadata: metadata, &block) + } end - def add_step(method_name, *args, condition: nil, &block) + def add_step(method_name, *args, condition: nil, metadata: {}, &block) step_class = - if method_name =~ /^(setup|action|teardown)/ - Lopata::ActionStep - else - Lopata::Step + case method_name + when /^(setup|action|teardown|verify)/ then Lopata::ActionStep + when /^(context)/ then Lopata::GroupStep + else Lopata::Step end - steps << step_class.new(method_name, *args, condition: condition, &block) + step = step_class.new(method_name, *args, condition: condition, shared_step: shared_step, group: group, &block) + step.metadata = metadata + steps << step end def steps @steps ||= [] end + def steps_with_hooks + s = [] + unless Lopata::Config.before_scenario_steps.empty? + s << Lopata::ActionStep.new(:setup, *Lopata::Config.before_scenario_steps) + end + + s += steps + + unless Lopata::Config.after_scenario_steps.empty? + s << Lopata::ActionStep.new(:teardown, *Lopata::Config.after_scenario_steps) + end + + s + end + def cleanup(*args, &block) add_step_as_is(:cleanup, *args, &block) end def add_step_as_is(method_name, *args, &block) @@ -185,14 +207,14 @@ end end end class Variant - attr_reader :key, :title, :value + attr_reader :key, :title, :value, :option - def initialize(key, title, value) - @key, @title, @value = key, title, check_lambda_arity(value) + def initialize(option, key, title, value) + @option, @key, @title, @value = option, key, title, check_lambda_arity(value) end def metadata(option_set) data = { key => value } if value.is_a? Hash @@ -200,10 +222,14 @@ sub_key = "%s_%s" % [key, k] data[sub_key.to_sym] = v end end + option.available_metadata_keys.each do |key| + data[key] = nil unless data.has_key?(key) + end + data.each do |key, v| data[key] = v.calculate(option_set) if v.is_a? CalculatedValue end data end @@ -239,18 +265,19 @@ @proc.call(option_set) end end class Option - attr_reader :variants + attr_reader :variants, :key def initialize(key, variants) + @key = key @variants = if variants.is_a? Hash - variants.map { |title, value| Variant.new(key, title, value) } + variants.map { |title, value| Variant.new(self, key, title, value) } else # Array of arrays of two elements - variants.map { |v| Variant.new(key, *v) } + variants.map { |v| Variant.new(self, key, *v) } end end # Variants to apply at one level def level_variants @@ -264,9 +291,14 @@ if @current >= variants.length @current = 0 @complete = true # all variants have been selected end selected_variant + end + + def available_metadata_keys + @available_metadata_keys ||= variants + .map(&:value).select { |v| v.is_a?(Hash) }.flat_map(&:keys).map { |k| "#{key}_#{k}".to_sym }.uniq end end class Diagonal < Option def level_variants