aboutsummaryrefslogtreecommitdiffstats
path: root/spec/mspec/lib/mspec/runner/actions/tag.rb
blob: 760152b2a34b55a8d0857a8445668062da0c3ee7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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