Module: Rubyzen::ExpectationHelpers
- Included in:
- Assertions
- Defined in:
- lib/rubyzen/expectation_helpers.rb
Overview
Shared helper methods for Rubyzen’s zen_* / assert_zen_* expectations —used by both the RSpec matchers (Matchers) and the Minitest assertions (Assertions).
Provides utilities for normalizing exception lists, extracting item details, matching items against allowlist/baseline entries, and formatting failure messages. These methods are framework-agnostic — they operate only on plain declaration objects and instance variables set by the caller.
Instance Method Summary collapse
-
#classify_items(subject_collection, allowlist: nil, baseline: nil) ⇒ Hash{Symbol => Array<String>}
Classifies items into violations, baseline matches, allowlist matches, and detects stale entries in either list.
-
#element_name(item) ⇒ String
Formats a human-readable description of an item for failure messages.
-
#exception_entry_matches_item?(entry, item) ⇒ Boolean
Checks whether a given exception entry string matches an item.
-
#formatted_matcher_groups ⇒ String?
Builds a formatted string of violations and stale entries for failure output.
-
#item_details(item) ⇒ Hash{Symbol => String, nil}
Extracts identifying details from a declaration item.
-
#item_identifiers(item) ⇒ Array<String>
Returns a list of unique identifier strings for an item, used for matching.
-
#message_for_failure(base_message) ⇒ String
Formats the failure message by combining the base message with custom messages and classified item details (violations, stale entries).
-
#normalize_exception_entries(entries) ⇒ Array<String>
Normalizes a list of exception entries into unique, non-blank strings.
Instance Method Details
#classify_items(subject_collection, allowlist: nil, baseline: nil) ⇒ Hash{Symbol => Array<String>}
Classifies items into violations, baseline matches, allowlist matches, and detects stale entries in either list.
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 |
# File 'lib/rubyzen/expectation_helpers.rb', line 71 def classify_items(subject_collection, allowlist: nil, baseline: nil) items = Array(subject_collection).compact normalized_allowlist = normalize_exception_entries(allowlist) normalized_baseline = normalize_exception_entries(baseline) matched_baseline_entries = [] matched_allowlist_entries = [] grouped_items = items.group_by do |item| matching_baseline_entry = normalized_baseline.find do |entry| exception_entry_matches_item?(entry, item) end if matching_baseline_entry matched_baseline_entries << matching_baseline_entry :baseline else matching_allowlist_entry = normalized_allowlist.find do |entry| exception_entry_matches_item?(entry, item) end if matching_allowlist_entry matched_allowlist_entries << matching_allowlist_entry :allowlist else :violations end end end classifications = { baseline: Array(grouped_items[:baseline]).map { |item| element_name(item) }, allowlist: Array(grouped_items[:allowlist]).map { |item| element_name(item) }, violations: Array(grouped_items[:violations]).map { |item| element_name(item) } } classifications.merge( stale_baseline: normalized_baseline - matched_baseline_entries.uniq, stale_allowlist: normalized_allowlist - matched_allowlist_entries.uniq ) end |
#element_name(item) ⇒ String
Formats a human-readable description of an item for failure messages.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/rubyzen/expectation_helpers.rb', line 116 def element_name(item) details = item_details(item) location = [details[:file_path], details[:line]].compact.join(':') case when details[:name] && details[:class_name] " - element: #{details[:name]}\n - class: #{details[:class_name]}\n - file: #{location}" when details[:name] " - element: #{details[:name]}\n - file: #{location}" when details[:class_name] " - class: #{details[:class_name]}\n - file: #{location}" else " - unknown element in #{location}" end end |
#exception_entry_matches_item?(entry, item) ⇒ Boolean
Checks whether a given exception entry string matches an item.
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rubyzen/expectation_helpers.rb', line 52 def exception_entry_matches_item?(entry, item) normalized_entry = entry.to_s.strip return false if normalized_entry.empty? details = item_details(item) return true if item_identifiers(item).include?(normalized_entry) file_path = details[:file_path] file_path && (file_path.end_with?(normalized_entry) || file_path.end_with?("/#{normalized_entry}")) end |
#formatted_matcher_groups ⇒ String?
Builds a formatted string of violations and stale entries for failure output.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/rubyzen/expectation_helpers.rb', line 135 def formatted_matcher_groups return unless defined?(@classified_items) && @classified_items sections = [] if @classified_items[:violations].any? sections << "Violations:\n#{@classified_items[:violations].join("\n")}" end if @classified_items[:stale_baseline].any? stale_entries = @classified_items[:stale_baseline].map { |entry| " - #{entry}" } sections << "Stale baseline entries:\n#{stale_entries.join("\n")}" end if @classified_items[:stale_allowlist].any? stale_entries = @classified_items[:stale_allowlist].map { |entry| " - #{entry}" } sections << "Stale allowlist entries:\n#{stale_entries.join("\n")}" end sections.join("\n") end |
#item_details(item) ⇒ Hash{Symbol => String, nil}
Extracts identifying details from a declaration item.
23 24 25 26 27 28 29 30 |
# File 'lib/rubyzen/expectation_helpers.rb', line 23 def item_details(item) { name: item.respond_to?(:name) ? item.name : nil, class_name: item.respond_to?(:class_name) ? item.class_name : nil, file_path: item.respond_to?(:file_path) ? item.file_path : 'Unknown file', line: item.respond_to?(:line) ? item.line : nil } end |
#item_identifiers(item) ⇒ Array<String>
Returns a list of unique identifier strings for an item, used for matching.
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/rubyzen/expectation_helpers.rb', line 36 def item_identifiers(item) details = item_details(item) identifiers = [details[:name], details[:class_name], details[:file_path]] if details[:line] identifiers << "#{details[:file_path]}:#{details[:line]}" end identifiers.compact.uniq end |
#message_for_failure(base_message) ⇒ String
Formats the failure message by combining the base message with custom messages and classified item details (violations, stale entries).
Works unchanged in both RSpec matchers and Minitest assertions, since it only reads instance variables set by the caller (+@failure_message+, @custom_message, @classified_items).
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/rubyzen/expectation_helpers.rb', line 166 def () return @failure_message if @failure_message details = formatted_matcher_groups if @custom_message if details && !details.empty? "#{@custom_message}\n#{details}" else @custom_message end elsif details && !details.empty? "#{}\n#{details}" else end end |
#normalize_exception_entries(entries) ⇒ Array<String>
Normalizes a list of exception entries into unique, non-blank strings.
15 16 17 |
# File 'lib/rubyzen/expectation_helpers.rb', line 15 def normalize_exception_entries(entries) Array(entries).flatten.compact.map(&:to_s).map(&:strip).reject(&:empty?).uniq end |