require 'lucid/ast/has_steps' require 'lucid/ast/names' require 'lucid/ast/empty_background' require 'lucid/ast/location' require 'lucid/unit' module Lucid module AST class Scenario #:nodoc: include HasSteps include Names include HasLocation attr_reader :feature_tags attr_accessor :feature def initialize(language, location, background, comment, tags, feature_tags, keyword, title, description, raw_steps) @language, @location, @background, @comment, @tags, @feature_tags, @keyword, @title, @description, @raw_steps = language, location, background, comment, tags, feature_tags, keyword, title, description, raw_steps @exception = @executed = nil attach_steps(@raw_steps) end def accept(visitor) return if Lucid.wants_to_quit visitor.visit_comment(@comment) unless @comment.empty? visitor.visit_tags(@tags) visitor.visit_scenario_name(@keyword, name, file_colon_line, source_indent(first_line_length)) skip_invoke! if @background.failed? with_visitor(visitor) do visitor.execute(self, skip_hooks?) end @executed = true end def to_units(background) [Unit.new(background.step_invocations + step_invocations)] end # Returns true if one or more steps failed. def failed? steps.failed? || !!@exception end def fail!(exception) @exception = exception @current_visitor.visit_exception(@exception, :failed) end # Returns true if all steps passed. def passed? !failed? end # Returns the first exception (if any). def exception @exception || steps.exception end # Returns the status. def status return :failed if @exception steps.status end def to_sexp sexp = [:scenario, line, @keyword, name] comment = @comment.to_sexp sexp += [comment] if comment tags = @tags.to_sexp sexp += tags if tags.any? sexp += steps.to_sexp if steps.any? sexp end def with_visitor(visitor) @current_visitor = visitor yield @current_visitor = nil end def skip_invoke! steps.skip_invoke! end def steps @steps ||= @background.step_collection(step_invocations) end private def step_invocations @raw_steps.map{|step| step.step_invocation} end def skip_hooks? @background.failed? || @executed end end end end