File: runner.rb

package info (click to toggle)
ruby-cucumber-core 16.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 764 kB
  • sloc: ruby: 5,074; makefile: 2
file content (164 lines) | stat: -rw-r--r-- 4,559 bytes parent folder | download
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# frozen_string_literal: true

require 'cucumber/core/test/timer'

module Cucumber
  module Core
    module Test
      class Runner
        attr_reader :event_bus, :running_test_case, :running_test_step
        private :event_bus, :running_test_case, :running_test_step

        def initialize(event_bus)
          @event_bus = event_bus
        end

        def test_case(test_case, &descend)
          @running_test_case = RunningTestCase.new
          @running_test_step = nil
          event_bus.test_case_started(test_case)
          descend.call(self)
          result = running_test_case.result
          result = Result::Undefined.new('The test case has no steps', Result::UnknownDuration.new, ["#{test_case.location}:in `#{test_case.name}'"]) if result.unknown?
          event_bus.test_case_finished(test_case, result)
          self
        end

        def test_step(test_step)
          @running_test_step = test_step
          event_bus.test_step_started test_step
          step_result = running_test_case.execute(test_step)
          event_bus.test_step_finished test_step, step_result
          @running_test_step = nil
          self
        end

        def around_hook(hook, &)
          result = running_test_case.execute(hook, &)
          event_bus.test_step_finished running_test_step, result if running_test_step
          @running_test_step = nil
          self
        end

        def done
          self
        end

        class RunningTestCase
          def initialize
            @timer = Timer.new.start
            @status = Status::Unknown.new(Result::Unknown.new)
          end

          def execute(test_step, &)
            status.execute(test_step, self, &)
          end

          def result
            status.result(@timer.duration)
          end

          def failed(step_result)
            @status = Status::Failing.new(step_result)
            self
          end

          def ambiguous(step_result)
            @status = Status::Ambiguous.new(step_result)
            self
          end

          def passed(step_result)
            @status = Status::Passing.new(step_result)
            self
          end

          def pending(_message, step_result)
            @status = Status::Pending.new(step_result)
            self
          end

          def skipped(step_result)
            @status = Status::Skipping.new(step_result)
            self
          end

          def undefined(step_result)
            failed(step_result)
            self
          end

          def exception(_step_exception, _step_result)
            self
          end

          def duration(_step_duration, _step_result)
            self
          end

          attr_reader :status
          private :status

          module Status
            class Base
              attr_reader :step_result
              private :step_result

              def initialize(step_result)
                @step_result = step_result
              end

              def execute(test_step, monitor, &)
                result = test_step.execute(monitor.result, &)
                result = result.with_message(%(Undefined step: "#{test_step.text}")) if result.undefined?
                result = result.with_appended_backtrace(test_step) unless test_step.hook?
                result.describe_to(monitor, result)
              end

              def result
                raise NoMethodError, 'Override me'
              end
            end

            class Unknown < Base
              def result(_duration)
                Result::Unknown.new
              end
            end

            class Passing < Base
              def result(duration)
                Result::Passed.new(duration)
              end
            end

            class Failing < Base
              def execute(test_step, monitor)
                result = test_step.skip(monitor.result)
                if result.undefined?
                  result = result.with_message(%(Undefined step: "#{test_step.text}"))
                  result = result.with_appended_backtrace(test_step)
                end
                result
              end

              def result(duration)
                step_result.with_duration(duration)
              end
            end

            Pending = Class.new(Failing)

            Ambiguous = Class.new(Failing)

            class Skipping < Failing
              def result(duration)
                step_result.with_duration(duration)
              end
            end
          end
        end
      end
    end
  end
end