Class: Canon::Comparison::XmlComparatorHelpers::AttributeFilter

Inherits:
Object
  • Object
show all
Defined in:
lib/canon/comparison/xml_comparator/attribute_filter.rb

Overview

Attribute filtering logic Handles filtering of attributes based on options and match settings

Class Method Summary collapse

Class Method Details

.filter(attributes, opts) ⇒ Hash

Filter attributes based on options

Parameters:

  • attributes (Array, Hash)

    Raw attributes

  • opts (Hash)

    Comparison options

Returns:

  • (Hash)

    Filtered attributes



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/canon/comparison/xml_comparator/attribute_filter.rb', line 17

def self.filter(attributes, opts)
  filtered = {}
  match_opts = opts[:match_opts]

  # Handle Canon::Xml::Node attribute format (array of AttributeNode)
  if attributes.is_a?(Array)
    filter_array_attributes(attributes, opts, match_opts, filtered)
  else
    # Handle Nokogiri and Moxml attribute formats (Hash-like)
    filter_hash_attributes(attributes, opts, match_opts, filtered)
  end

  filtered
end

.filter_array_attributes(attributes, opts, match_opts, filtered) ⇒ Object

Filter array-format attributes (Canon::Xml::Node)

Parameters:

  • attributes (Array)

    Array of AttributeNode objects

  • opts (Hash)

    Comparison options

  • match_opts (Hash)

    Resolved match options

  • filtered (Hash)

    Output hash to populate



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/canon/comparison/xml_comparator/attribute_filter.rb', line 38

def self.filter_array_attributes(attributes, opts, match_opts, filtered)
  attributes.each do |attr|
    name = attr.name
    value = attr.value

    # Skip namespace declarations - they're handled separately
    next if namespace_declaration?(name)

    # Skip if attribute name should be ignored
    next if ignore_by_name?(name, opts)

    # Skip if attribute content should be ignored
    next if ignore_by_content?(value, opts)

    # Apply match options for attribute values
    behavior = match_opts[:attribute_values] || :strict
    value = MatchOptions.process_attribute_value(value, behavior)

    filtered[name] = value
  end
end

.filter_hash_attributes(attributes, opts, match_opts, filtered) ⇒ Object

Filter hash-format attributes (Nokogiri/Moxml)

Parameters:

  • attributes (Hash)

    Hash-like attributes

  • opts (Hash)

    Comparison options

  • match_opts (Hash)

    Resolved match options

  • filtered (Hash)

    Output hash to populate



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/canon/comparison/xml_comparator/attribute_filter.rb', line 66

def self.filter_hash_attributes(attributes, opts, match_opts, filtered)
  attributes.each do |key, val|
    # Normalize key and value
    name, value = normalize_attribute_pair(key, val)

    # Skip namespace declarations - they're handled separately
    next if namespace_declaration?(name)

    # Skip if attribute name should be ignored
    next if ignore_by_name?(name, opts)

    # Skip if attribute content should be ignored
    next if ignore_by_content?(value, opts)

    # Apply match options for attribute values
    behavior = match_opts[:attribute_values] || :strict
    value = MatchOptions.process_attribute_value(value, behavior)

    filtered[name] = value
  end
end

.ignore_by_content?(value, opts) ⇒ Boolean

Check if attribute should be ignored by content

Parameters:

  • value (String)

    Attribute value

  • opts (Hash)

    Comparison options

Returns:

  • (Boolean)

    true if should ignore



119
120
121
122
123
# File 'lib/canon/comparison/xml_comparator/attribute_filter.rb', line 119

def self.ignore_by_content?(value, opts)
  opts[:ignore_attr_content].any? do |pattern|
    value.to_s.include?(pattern)
  end
end

.ignore_by_name?(name, opts) ⇒ Boolean

Check if attribute should be ignored by name

Parameters:

  • name (String)

    Attribute name

  • opts (Hash)

    Comparison options

Returns:

  • (Boolean)

    true if should ignore



110
111
112
# File 'lib/canon/comparison/xml_comparator/attribute_filter.rb', line 110

def self.ignore_by_name?(name, opts)
  opts[:ignore_attrs_by_name].any? { |pattern| name.include?(pattern) }
end

.namespace_declaration?(attr_name) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/canon/comparison/xml_comparator/attribute_filter.rb', line 125

def self.namespace_declaration?(attr_name)
  Canon::Xml::NamespaceHelper.namespace_declaration?(attr_name)
end

.normalize_attribute_pair(key, val) ⇒ Array<String, String>

Normalize attribute key-value pair from different formats

Parameters:

  • key (Object)

    Attribute key (String or Attribute object)

  • val (Object)

    Attribute value

Returns:

  • (Array<String, String>)

    Normalized [name, value] pair



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/canon/comparison/xml_comparator/attribute_filter.rb', line 93

def self.normalize_attribute_pair(key, val)
  if key.is_a?(String)
    name = key
    value = val.is_a?(String) ? val : val.value
  else
    name = key.name
    value = key.value
  end

  [name, value]
end