This file is indexed.

/usr/lib/python3/dist-packages/behave/formatter/tags.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
# -*- coding: utf-8 -*-
"""
Collects data how often a tag count is used and where.

EXAMPLE:

    $ behave --dry-run -f tag_counts features/
"""


from behave.formatter.base import Formatter
from behave.textutil import compute_words_maxsize, text as _text
import six


# -----------------------------------------------------------------------------
# CLASS: AbstractTagsFormatter
# -----------------------------------------------------------------------------
class AbstractTagsFormatter(Formatter):
    """
    Abstract base class for formatter that collect information on tags.

    .. note::
        Supports dry-run mode for faster feedback.
    """
    with_tag_inheritance = False

    def __init__(self, stream_opener, config):
        super(AbstractTagsFormatter, self).__init__(stream_opener, config)
        self.tag_counts = {}
        self._uri = None
        self._feature_tags = None
        self._scenario_outline_tags = None

    # -- Formatter API:
    def uri(self, uri):
        self._uri = uri

    def feature(self, feature):
        self._feature_tags = feature.tags
        self.record_tags(feature.tags, feature)

    def scenario(self, scenario):
        tags = set(scenario.tags)
        if self.with_tag_inheritance:
            tags.update(self._feature_tags)
        self.record_tags(tags, scenario)

    def scenario_outline(self, scenario_outline):
        self._scenario_outline_tags = scenario_outline.tags
        self.record_tags(scenario_outline.tags, scenario_outline)

    def examples(self, examples):
        tags = set(examples.tags)
        if self.with_tag_inheritance:
            tags.update(self._scenario_outline_tags)
            tags.update(self._feature_tags)
        self.record_tags(tags, examples)

    def close(self):
        """Emit tag count reports."""
        # -- ENSURE: Output stream is open.
        self.stream = self.open()
        self.report_tags()
        self.close_stream()

    # -- SPECIFIC API:
    def record_tags(self, tags, model_element):
        for tag in tags:
            if tag not in self.tag_counts:
                self.tag_counts[tag] = []
            self.tag_counts[tag].append(model_element)

    def report_tags(self):
        raise NotImplementedError


# -----------------------------------------------------------------------------
# CLASS: TagsFormatter
# -----------------------------------------------------------------------------
class TagsFormatter(AbstractTagsFormatter):
    """
    Formatter that collects information:

      * which tags exist
      * how often a tag is used (counts)
      * usage context/category: feature, scenario, ...

    .. note::
        Supports dry-run mode for faster feedback.
    """
    name = "tags"
    description = "Shows tags (and how often they are used)."
    with_tag_inheritance = False
    show_ordered_by_usage = False

    def report_tags(self):
        self.report_tag_counts()
        if self.show_ordered_by_usage:
            self.report_tag_counts_by_usage()

    @staticmethod
    def get_tag_count_details(tag_count):
        details = {}
        for element in tag_count:
            category = element.keyword.lower()
            if category not in details:
                details[category] = 0
            details[category] += 1

        parts = []
        if len(details) == 1:
            parts.append(list(details.keys())[0])
        else:
            for category in sorted(details.keys()):
                text = "%s: %d" % (category, details[category])
                parts.append(text)
        return ", ".join(parts)

    def report_tag_counts(self):
        # -- PREPARE REPORT:
        ordered_tags = sorted(list(self.tag_counts.keys()))
        tag_maxsize = compute_words_maxsize(ordered_tags)
        schema = "  @%-" + _text(tag_maxsize) + "s %4d    (used for %s)\n"

        # -- EMIT REPORT:
        self.stream.write("TAG COUNTS (alphabetically sorted):\n")
        for tag in ordered_tags:
            tag_data = self.tag_counts[tag]
            counts = len(tag_data)
            details = self.get_tag_count_details(tag_data)
            self.stream.write(schema % (tag, counts, details))
        self.stream.write("\n")

    def report_tag_counts_by_usage(self):
        # -- PREPARE REPORT:
        compare_tag_counts_size = lambda x: len(self.tag_counts[x])
        ordered_tags = sorted(list(self.tag_counts.keys()),
                              key=compare_tag_counts_size)
        tag_maxsize = compute_words_maxsize(ordered_tags)
        schema = "  @%-" + _text(tag_maxsize) + "s %4d    (used for %s)\n"

        # -- EMIT REPORT:
        self.stream.write("TAG COUNTS (most often used first):\n")
        for tag in ordered_tags:
            tag_data = self.tag_counts[tag]
            counts = len(tag_data)
            details = self.get_tag_count_details(tag_data)
            self.stream.write(schema % (tag, counts, details))
        self.stream.write("\n")


# -----------------------------------------------------------------------------
# CLASS: TagsLocationFormatter
# -----------------------------------------------------------------------------
class TagsLocationFormatter(AbstractTagsFormatter):
    """
    Formatter that collects information:

      * which tags exist
      * where the tags are used (location)

    .. note::
        Supports dry-run mode for faster feedback.
    """
    name = "tags.location"
    description = "Shows tags and the location where they are used."
    with_tag_inheritance = False

    def report_tags(self):
        self.report_tags_by_locations()

    def report_tags_by_locations(self):
        # -- PREPARE REPORT:
        locations = set()
        for tag_elements in list(self.tag_counts.values()):
            locations.update([six.text_type(x.location) for x in tag_elements])
        location_column_size = compute_words_maxsize(locations)
        schema = "    %-" + _text(location_column_size) + "s   %s\n"

        # -- EMIT REPORT:
        self.stream.write("TAG LOCATIONS (alphabetically ordered):\n")
        for tag in sorted(self.tag_counts.keys()):
            self.stream.write("  @%s:\n" % tag)
            for element in self.tag_counts[tag]:
                info = "%s: %s" % (element.keyword, element.name)
                self.stream.write(schema % (element.location, info))
            self.stream.write("\n")
        self.stream.write("\n")