mspec/lib/mspec/runner/actions/tag.rb
require 'mspec/runner/actions/filter'
# TagAction - Write tagged spec description string to a
# tag file associated with each spec file.
#
# The action is triggered by specs whose descriptions
# match the filter created with 'tags' and/or 'desc'
#
# The action fires in the :after event, after the spec
# had been run. The action fires if the outcome of
# running the spec matches 'outcome'.
#
# The arguments are:
#
# action: :add, :del
# outcome: :pass, :fail, :all
# tag: the tag to create/delete
# comment: the comment to create
# tags: zero or more tags to get matching
# spec description strings from
# desc: zero or more strings to match the
# spec description strings
class TagAction < ActionFilter
def initialize(action, outcome, tag, comment, tags=nil, descs=nil)
super tags, descs
@action = action
@outcome = outcome
@tag = tag
@comment = comment
@report = []
@exception = false
end
# Returns true if there are no _tag_ or _description_ filters. This
# means that a TagAction matches any example by default. Otherwise,
# returns true if either the _tag_ or the _description_ filter
# matches +string+.
def ===(string)
return true unless @sfilter or @tfilter
@sfilter === string or @tfilter === string
end
# Callback for the MSpec :before event. Resets the +#exception?+
# flag to false.
def before(state)
@exception = false
end
# Callback for the MSpec :exception event. Sets the +#exception?+
# flag to true.
def exception(exception)
@exception = true
end
# Callback for the MSpec :after event. Performs the tag action
# depending on the type of action and the outcome of evaluating
# the example. See +TagAction+ for a description of the actions.
def after(state)
if self === state.description and outcome?
tag = SpecTag.new
tag.tag = @tag
tag.comment = @comment
tag.description = state.description
case @action
when :add
changed = MSpec.write_tag tag
when :del
changed = MSpec.delete_tag tag
end
@report << state.description if changed
end
end
# Returns true if the result of evaluating the example matches
# the _outcome_ registered for this tag action. See +TagAction+
# for a description of the _outcome_ types.
def outcome?
@outcome == :all or
(@outcome == :pass and not exception?) or
(@outcome == :fail and exception?)
end
# Returns true if an exception was raised while evaluating the
# current example.
def exception?
@exception
end
def report
@report.join("\n") + "\n"
end
private :report
# Callback for the MSpec :finish event. Prints the actions
# performed while evaluating the examples.
def finish
case @action
when :add
if @report.empty?
print "\nTagAction: no specs were tagged with '#{@tag}'\n"
else
print "\nTagAction: specs tagged with '#{@tag}':\n\n"
print report
end
when :del
if @report.empty?
print "\nTagAction: no tags '#{@tag}' were deleted\n"
else
print "\nTagAction: tag '#{@tag}' deleted for specs:\n\n"
print report
end
end
end
def register
super
MSpec.register :before, self
MSpec.register :exception, self
MSpec.register :after, self
MSpec.register :finish, self
end
def unregister
super
MSpec.unregister :before, self
MSpec.unregister :exception, self
MSpec.unregister :after, self
MSpec.unregister :finish, self
end
end