Class: Canon::Comparison::ProfileDefinition

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

Overview

Profile definition DSL with full validation

Provides a clean, validated way to define custom comparison profiles. Catches errors at definition time with clear, actionable messages.

Examples:

Define a custom profile

Canon::Comparison.define_profile(:my_custom) do
  text_content :normalize
  comments :ignore
  preprocessing :rendered
end

Constant Summary collapse

VALID_DIMENSIONS =

All valid dimensions for XML/HTML comparison These must match MatchOptions::Xml::MATCH_DIMENSIONS

%i[
  text_content
  structural_whitespace
  attribute_presence
  attribute_order
  attribute_values
  element_position
  comments
].freeze
DIMENSION_BEHAVIORS =

Behaviors valid for each dimension Maps dimension name to array of valid behavior symbols

{
  text_content: %i[strict normalize ignore],
  structural_whitespace: %i[strict normalize ignore],
  attribute_presence: %i[strict ignore],
  attribute_order: %i[strict ignore],
  attribute_values: %i[strict strip compact normalize ignore],
  element_position: %i[strict ignore],
  comments: %i[strict ignore],
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ ProfileDefinition

Initialize a new profile definition

Parameters:

  • name (Symbol)

    Profile name



48
49
50
51
# File 'lib/canon/comparison/profile_definition.rb', line 48

def initialize(name)
  @name = name
  @settings = {}
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



43
44
45
# File 'lib/canon/comparison/profile_definition.rb', line 43

def name
  @name
end

#settingsObject (readonly)

Returns the value of attribute settings.



43
44
45
# File 'lib/canon/comparison/profile_definition.rb', line 43

def settings
  @settings
end

Class Method Details

.define(name) {|ProfileDefinition| ... } ⇒ Hash

Define a profile using DSL syntax

Parameters:

  • name (Symbol)

    Profile name

Yields:

Returns:

  • (Hash)

    Profile settings hash

Raises:



59
60
61
62
63
64
# File 'lib/canon/comparison/profile_definition.rb', line 59

def self.define(name, &block)
  definition = new(name)
  definition.instance_eval(&block) if block
  definition.validate!
  definition.to_h
end

Instance Method Details

#preprocessing(mode) ⇒ Object

Set preprocessing mode

Parameters:

  • mode (Symbol)

    Preprocessing mode

Raises:



77
78
79
80
81
82
83
84
85
# File 'lib/canon/comparison/profile_definition.rb', line 77

def preprocessing(mode)
  unless MatchOptions::PREPROCESSING_OPTIONS.include?(mode)
    raise ProfileError,
          "Invalid preprocessing mode: #{mode}. " \
          "Valid options: #{MatchOptions::PREPROCESSING_OPTIONS.join(', ')}"
  end

  @settings[:preprocessing] = mode
end

#semantic_diff(enabled: true) ⇒ Object

Enable/disable semantic diff

Parameters:

  • enabled (Boolean) (defaults to: true)

    Whether to enable semantic diff (default: true)



90
91
92
# File 'lib/canon/comparison/profile_definition.rb', line 90

def semantic_diff(enabled: true)
  @settings[:semantic_diff] = enabled
end

#similarity_threshold(value) ⇒ Object

Set similarity threshold for semantic matching

Parameters:

  • value (Numeric)

    Threshold between 0 and 1

Raises:



98
99
100
101
102
103
104
105
# File 'lib/canon/comparison/profile_definition.rb', line 98

def similarity_threshold(value)
  unless value.is_a?(Numeric) && value >= 0 && value <= 1
    raise ProfileError,
          "Similarity threshold must be between 0 and 1, got: #{value}"
  end

  @settings[:similarity_threshold] = value
end

#to_hHash

Convert to hash

Returns:

  • (Hash)

    Profile settings



119
120
121
# File 'lib/canon/comparison/profile_definition.rb', line 119

def to_h
  @settings.dup
end

#validate!Object

Validate the profile definition

Raises:



110
111
112
113
114
# File 'lib/canon/comparison/profile_definition.rb', line 110

def validate!
  @settings.each do |key, value|
    validate_dimension!(key, value) if VALID_DIMENSIONS.include?(key)
  end
end