Module: Contrast::Utils::Assess::TaggedUtils

Included in:
Agent::Assess::Property::Tagged
Defined in:
lib/contrast/utils/assess/property/tagged_utils.rb

Overview

This module will include all methods for some internal validations in the Tagged property module and some other module methods from the same place, so we can ease the main module This module includes simple methods for the tags like adding tags, getting tags, deleting tags and similar

Instance Method Summary collapse

Instance Method Details

#add_tag(label, range) ⇒ Object

Given a tag name and range object, add a new tag to this collection. If the given range touches an existing tag, we’ll combine the two, adjusting the existing one and dropping this new one.

Parameters:

  • label (String)

    the name of the tag

  • range (Range)

    the Range that the tag covers, inclusive to exclusive



43
44
45
46
47
48
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 43

def add_tag label, range
  length = range.end - range.begin
  tag = Contrast::Agent::Assess::Tag.new(label, length, range.begin)
  existing = fetch_tag(label)
  tags[label] = Contrast::Utils::TagUtil.ordered_merge(existing, tag)
end

#any_tags_between?(start, finish) ⇒ Boolean

Similar to #tracked?, but limited to a given range.

Parameters:

  • start (Integer)

    the inclusive start index to check.

  • finish (Integer)

    the exclusive end index to check.

Returns:

  • (Boolean)


26
27
28
29
30
31
32
33
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 26

def any_tags_between? start, finish
  return false unless tracked?

  tags.each_value do |tag_array|
    return true if tag_array.any? { |tag| tag.overlaps?(start, finish) }
  end
  false
end

#cleanup_tagsObject

Calls merge to combine touching or overlapping tags Deletes empty tags



95
96
97
98
99
100
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 95

def cleanup_tags
  return unless tracked?

  Contrast::Utils::TagUtil.merge_tags(tags)
  tags.delete_if { |_, value| value.empty? }
end

#clear_tagsObject

Reset the tag hash



81
82
83
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 81

def clear_tags
  tags.clear if tracked?
end

#delete_tags(label) ⇒ Object

Remove all tags with a given label



76
77
78
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 76

def delete_tags label
  tags.delete(label) if tracked?
end

#fetch_tag(label) ⇒ Array<Contrast::Agent::Assess::Tag>

We’ll use this as a helper method to retrieve tags from the hash. Because the hash auto-populates an empty array when we try to access a tag in it, we cannot use the [] method without side effect. To get around this, we’ll use a fetch work around.

Parameters:

  • label (Symbol)

    the label to look up

Returns:



71
72
73
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 71

def fetch_tag label
  get_tags.fetch(label, nil) if tracked?
end

#get_tagsHash<Contrast::Agent::Assess::Tag>

Returns a list of all current tags.



57
58
59
60
61
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 57

def get_tags # rubocop:disable Naming/AccessorMethodName
  return Contrast::Utils::ObjectShare::EMPTY_HASH unless tracked?

  tags
end

#set_tags(label, tag_ranges) ⇒ Object



50
51
52
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 50

def set_tags label, tag_ranges
  tags[label] = tag_ranges
end

#tag_keysObject

Returns a list of all current tag labels, most likely to be used for a splat operation



87
88
89
90
91
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 87

def tag_keys
  return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless tracked?

  tags.keys
end

#tagged?(label) ⇒ Boolean

Is the given tag present? Used in testing, so found by ‘be_tagged`, if you’re grepping for it

Parameters:

  • label (Symbol)

    the tag to check for

Returns:

  • (Boolean)


17
18
19
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 17

def tagged? label
  tracked? && tags.key?(label)
end

#tags_at(idx) ⇒ Array<Contrast::Agent::Assess::Tag>

Find all of the ranges that span a given index. This is used in propagation when we need to shift tags about. For instance, in the append method when we need to see if any tag at the end needs to be expanded out to the size of the new String.

Note: Tags do not know their key, so this is only the range covered

Parameters:

  • idx (Integer)

    the index to check for tags

Returns:



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 112

def tags_at idx
  return Contrast::Utils::ObjectShare::EMPTY_ARRAY unless tracked?

  at = []
  tags.each_value do |tag_array|
    tag_array.each do |tag|
      if tag.covers?(idx)
        at << tag
      elsif tag.above?(idx)
        break
      end
    end
  end
  at
end

#tags_at_range(range) ⇒ Hash{String => Contrast::Agent::Assess::Tag}

given a range, select all tags in that range the selected tags are shifted such that the start index of the new tag (0) aligns with the given start index in the range

current tags: 5-15 range : 5-10 result : 0-05

Note that we disable Lint/DuplicateBranch in this branch in order list out all tag range cases in the proper order to make this easier to understand

Parameters:

  • range (Range)

    the span to check, inclusive to exclusive

Returns:



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/contrast/utils/assess/property/tagged_utils.rb', line 143

def tags_at_range range
  return Contrast::Utils::ObjectShare::EMPTY_HASH unless tracked?

  at = Hash.new { |h, k| h[k] = [] }
  tags.each_pair do |key, value|
    add = nil
    value.each do |tag|
      within_range = resize_to_range(tag, range)
      if within_range
        add ||= []
        add << within_range
      end
    end
    next unless add&.any?

    at[key] = add
  end
  at
end