This file is indexed.

/usr/lib/python3/dist-packages/behave/formatter/progress.py is in python3-behave 1.2.5-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# -*- coding: utf-8 -*-
"""
Provides 2 dotted progress formatters:

  * ScenarioProgressFormatter (scope: scenario)
  * StepProgressFormatter (scope: step)

A "dot" character that represents the result status is printed after
executing a scope item.
"""


from behave.formatter.base import Formatter
import os
import os.path
import six


# -----------------------------------------------------------------------------
# CLASS: ProgressFormatterBase
# -----------------------------------------------------------------------------
class ProgressFormatterBase(Formatter):
    """
    Provides formatter base class for different variants of progress formatters.
    A progress formatter show an abbreviated, compact dotted progress bar,
    similar to unittest output (in terse mode).
    """
    # -- MAP: step.status to short dot_status representation.
    dot_status = {
        "passed":    ".",
        "failed":    "F",
        "error":     "E",   # Caught exception, but not an AssertionError
        "skipped":   "S",
        "untested":  "_",
        "undefined": "U",
    }
    show_timings = False

    def __init__(self, stream_opener, config):
        super(ProgressFormatterBase, self).__init__(stream_opener, config)
        # -- ENSURE: Output stream is open.
        self.stream = self.open()
        self.steps = []
        self.failures = []
        self.current_feature  = None
        self.current_scenario = None
        self.show_timings = config.show_timings and self.show_timings

    def reset(self):
        self.steps = []
        self.failures = []
        self.current_feature  = None
        self.current_scenario = None

    # -- FORMATTER API:
    def feature(self, feature):
        self.current_feature = feature
        short_filename = os.path.relpath(feature.filename, os.getcwd())
        self.stream.write("%s  " % six.text_type(short_filename))
        self.stream.flush()

    def background(self, background):
        pass

    def scenario(self, scenario):
        """
        Process the next scenario.
        But first allow to report the status on the last scenario.
        """
        self.report_scenario_completed()
        self.current_scenario = scenario

    def scenario_outline(self, outline):
        self.current_scenario = outline

    def step(self, step):
        self.steps.append(step)

    def result(self, result):
        self.steps.pop(0)
        self.report_step_progress(result)

    def eof(self):
        """
        Called at end of a feature.
        It would be better to have a hook that is called after all features.
        """
        self.report_scenario_completed()
        self.report_feature_completed()
        self.report_failures()
        self.stream.flush()
        self.reset()

    # -- SPECIFIC PART:
    def report_step_progress(self, result):
        """
        Report the progress on the current step.
        The default implementation is empty.
        It should be override by a concrete class.
        """
        pass

    def report_scenario_progress(self):
        """
        Report the progress for the current/last scenario.
        The default implementation is empty.
        It should be override by a concrete class.
        """
        pass

    def report_feature_completed(self):
        """Hook called when a feature is completed to perform the last tasks.
        """
        pass

    def report_scenario_completed(self):
        """Hook called when a scenario is completed to perform the last tasks.
        """
        self.report_scenario_progress()

    def report_feature_duration(self):
        if self.show_timings and self.current_feature:
            self.stream.write("  # %.3fs" % self.current_feature.duration)
        self.stream.write("\n")

    def report_scenario_duration(self):
        if self.show_timings and self.current_scenario:
            self.stream.write("  # %.3fs" % self.current_scenario.duration)
        self.stream.write("\n")

    def report_failures(self):
        if self.failures:
            separator = "-" * 80
            self.stream.write("%s\n" % separator)
            for result in self.failures:
                self.stream.write("FAILURE in step '%s':\n" % result.name)
                self.stream.write("  Feature:  %s\n" % result.feature.name)
                self.stream.write("  Scenario: %s\n" % result.scenario.name)
                self.stream.write("%s\n" % result.error_message)
                if result.exception:
                    self.stream.write("exception: %s\n" % result.exception)
            self.stream.write("%s\n" % separator)


# -----------------------------------------------------------------------------
# CLASS: ScenarioProgressFormatter
# -----------------------------------------------------------------------------
class ScenarioProgressFormatter(ProgressFormatterBase):
    """
    Report dotted progress for each scenario similar to unittest.
    """
    name = "progress"
    description = "Shows dotted progress for each executed scenario."

    def report_scenario_progress(self):
        """
        Report the progress for the current/last scenario.
        """
        if not self.current_scenario:
            return  # SKIP: No results to report for first scenario.
        # -- NORMAL-CASE:
        status = self.current_scenario.status
        dot_status = self.dot_status[status]
        if status == "failed":
            # MAYBE TODO: self.failures.append(result)
            pass
        self.stream.write(dot_status)
        self.stream.flush()

    def report_feature_completed(self):
        self.report_feature_duration()

# -----------------------------------------------------------------------------
# CLASS: StepProgressFormatter
# -----------------------------------------------------------------------------
class StepProgressFormatter(ProgressFormatterBase):
    """
    Report dotted progress for each step similar to unittest.
    """
    name = "progress2"
    description = "Shows dotted progress for each executed step."

    def report_step_progress(self, result):
        """
        Report the progress for each step.
        """
        dot_status = self.dot_status[result.status]
        if result.status == "failed":
            if (result.exception and
                not isinstance(result.exception, AssertionError)):
                # -- ISA-ERROR: Some Exception
                dot_status = self.dot_status["error"]
            result.feature  = self.current_feature
            result.scenario = self.current_scenario
            self.failures.append(result)
        self.stream.write(dot_status)
        self.stream.flush()

    def report_feature_completed(self):
        self.report_feature_duration()


# -----------------------------------------------------------------------------
# CLASS: ScenarioStepProgressFormatter
# -----------------------------------------------------------------------------
class ScenarioStepProgressFormatter(StepProgressFormatter):
    """
    Shows detailed dotted progress for both each step of a scenario.
    Differs from StepProgressFormatter by:

      * showing scenario names (as prefix scenario step progress)
      * showing failures after each scenario (if necessary)

    EXAMPLE:
        $ behave -f progress3 features
        Feature with failing scenario    # features/failing_scenario.feature
            Simple scenario with last failing step  ....F
        -----------------------------------------------------------------------
        FAILURE in step 'last step fails' (features/failing_scenario.feature:7):
        Assertion Failed: xxx
        -----------------------------------------------------------------------
    """
    name = "progress3"
    description = "Shows detailed progress for each step of a scenario."
    indent_size = 2
    scenario_prefix = " " * indent_size

    # -- FORMATTER API:
    def feature(self, feature):
        self.current_feature = feature
        short_filename = os.path.relpath(feature.filename, os.getcwd())
        self.stream.write("%s    # %s" % (feature.name, short_filename))

    def scenario(self, scenario):
        """Process the next scenario."""
        # -- LAST SCENARIO: Report failures (if any).
        self.report_scenario_completed()

        # -- NEW SCENARIO:
        assert not self.failures
        self.current_scenario = scenario
        scenario_name = scenario.name
        if scenario_name:
            scenario_name += " "
        self.stream.write("%s%s " % (self.scenario_prefix, scenario_name))
        self.stream.flush()

    # -- DISABLED:
    # def eof(self):
    #     has_scenarios = self.current_feature and self.current_scenario
    #     super(ScenarioStepProgressFormatter, self).eof()
    #     if has_scenarios:
    #         # -- EMPTY-LINE between 2 features.
    #         self.stream.write("\n")

    # -- PROGRESS FORMATTER DETAILS:
    # @overriden
    def report_feature_completed(self):
        # -- SKIP: self.report_feature_duration()
        has_scenarios = self.current_feature and self.current_scenario
        if has_scenarios:
            # -- EMPTY-LINE between 2 features.
            self.stream.write("\n")

    def report_scenario_completed(self):
        self.report_scenario_progress()
        self.report_scenario_duration()
        self.report_failures()
        self.failures = []

    def report_failures(self):
        if self.failures:
            separator = "-" * 80
            self.stream.write("%s\n" % separator)
            for failure in self.failures:
                self.stream.write("FAILURE in step '%s' (%s):\n" % \
                                  (failure.name, failure.location))
                self.stream.write("%s\n" % failure.error_message)
                self.stream.write("%s\n" % separator)
            self.stream.flush()