Class: SvgConform::ValidationContext

Inherits:
Object
  • Object
show all
Defined in:
lib/svg_conform/validation_context.rb

Overview

Context object passed to rules during validation

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, profile) ⇒ ValidationContext

Returns a new instance of ValidationContext.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/svg_conform/validation_context.rb', line 11

def initialize(document, profile)
  @document = document
  @profile = profile
  @errors = []
  @warnings = []
  @validity_errors = []
  @infos = []
  @data = {}
  @structurally_invalid_node_ids = Set.new
  @node_id_cache = {}
  @cache_populated = false
  @reference_manifest = References::ReferenceManifest.new(
    source_document: document.file_path,
  )
end

Instance Attribute Details

#documentObject (readonly)

Returns the value of attribute document.



8
9
10
# File 'lib/svg_conform/validation_context.rb', line 8

def document
  @document
end

#errorsObject (readonly)

Returns the value of attribute errors.



8
9
10
# File 'lib/svg_conform/validation_context.rb', line 8

def errors
  @errors
end

#fixesObject (readonly)

Returns the value of attribute fixes.



8
9
10
# File 'lib/svg_conform/validation_context.rb', line 8

def fixes
  @fixes
end

#profileObject (readonly)

Returns the value of attribute profile.



8
9
10
# File 'lib/svg_conform/validation_context.rb', line 8

def profile
  @profile
end

#reference_manifestObject (readonly)

Returns the value of attribute reference_manifest.



8
9
10
# File 'lib/svg_conform/validation_context.rb', line 8

def reference_manifest
  @reference_manifest
end

#validity_errorsObject (readonly)

Returns the value of attribute validity_errors.



8
9
10
# File 'lib/svg_conform/validation_context.rb', line 8

def validity_errors
  @validity_errors
end

#warningsObject (readonly)

Returns the value of attribute warnings.



8
9
10
# File 'lib/svg_conform/validation_context.rb', line 8

def warnings
  @warnings
end

Instance Method Details

#add_error(node:, message:, rule: nil, requirement: nil, requirement_id: nil, severity: nil, fix: nil, data: {}) ⇒ Object



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
# File 'lib/svg_conform/validation_context.rb', line 64

def add_error(node:, message:, rule: nil, requirement: nil,
requirement_id: nil, severity: nil, fix: nil, data: {})
  # Support both old rule system and new requirements system
  rule_or_requirement = requirement || rule

  error = ValidationIssue.new(
    type: :error,
    rule: rule_or_requirement,
    node: node,
    message: message,
    fix: fix,
    data: data,
    requirement_id: requirement_id,
    severity: severity,
  )

  # Handle special severity types
  if severity == :validity_error
    @validity_errors << error
  else
    @errors << error
  end

  error
end

#add_external_reference_notice(node:, reference:, message: nil) ⇒ Object

Add notice for external references (not errors)



156
157
158
159
160
161
162
163
164
165
# File 'lib/svg_conform/validation_context.rb', line 156

def add_external_reference_notice(node:, reference:, message: nil)
  notice = ValidationNotice.new(
    type: :external_reference,
    node: node,
    message: message || "External reference: #{reference.value}",
    data: { reference: reference },
  )
  @infos << notice
  notice
end

#add_fix(fix) ⇒ Object



102
103
104
# File 'lib/svg_conform/validation_context.rb', line 102

def add_fix(fix)
  @fixes << fix
end

#add_warning(rule:, node:, message:, fix: nil) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
# File 'lib/svg_conform/validation_context.rb', line 90

def add_warning(rule:, node:, message:, fix: nil)
  warning = ValidationIssue.new(
    type: :warning,
    rule: rule,
    node: node,
    message: message,
    fix: fix,
  )
  @warnings << warning
  warning
end

#fixable_countObject



122
123
124
# File 'lib/svg_conform/validation_context.rb', line 122

def fixable_count
  (@errors + @warnings).count(&:fixable?)
end

#generate_node_id(node) ⇒ Object

Generate a unique identifier for a node based on its path Builds a stable path by walking up the parent chain OPTIMIZED: Lazy cache population - populate entire cache on first call



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/svg_conform/validation_context.rb', line 170

def generate_node_id(node)
  return nil unless node.respond_to?(:name)

  # Populate cache for ALL nodes on first access
  unless @cache_populated
    populate_node_id_cache
    @cache_populated = true
  end

  # Try cache lookup first
  cached_id = @node_id_cache[node]
  return cached_id if cached_id

  # Fall back to building path if node not in cache
  # (happens when different traversals create different wrapper objects)
  build_node_path(node)
end

#get_data(key) ⇒ Object



130
131
132
# File 'lib/svg_conform/validation_context.rb', line 130

def get_data(key)
  @data[key]
end

#has_errors?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/svg_conform/validation_context.rb', line 106

def has_errors?
  !@errors.empty?
end

#has_fixes?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/svg_conform/validation_context.rb', line 114

def has_fixes?
  !@fixes.empty?
end

#has_warnings?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/svg_conform/validation_context.rb', line 110

def has_warnings?
  !@warnings.empty?
end

#id_defined?(id_value) ⇒ Boolean

Check if ID exists in manifest

Returns:

  • (Boolean)


151
152
153
# File 'lib/svg_conform/validation_context.rb', line 151

def id_defined?(id_value)
  @reference_manifest.id_defined?(id_value)
end

#issue_countObject



118
119
120
# File 'lib/svg_conform/validation_context.rb', line 118

def issue_count
  @errors.size + @warnings.size
end

#mark_descendants_invalid(node) ⇒ Object

Mark all descendants of a node as structurally invalid



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/svg_conform/validation_context.rb', line 41

def mark_descendants_invalid(node)
  # In SAX mode, ElementProxy doesn't have children yet
  # Children will be validated individually and will check parent validity
  return unless node.respond_to?(:children) && node.children

  node.children.each do |child|
    child_id = generate_node_id(child)
    next if child_id.nil? # Skip if can't generate ID

    @structurally_invalid_node_ids.add(child_id)
    # Recursively mark descendants
    mark_descendants_invalid(child)
  end
end

#mark_node_structurally_invalid(node) ⇒ Object

Mark a node as structurally invalid (e.g., invalid parent-child relationship) Other requirements should skip attribute validation on these nodes Also marks all descendants as invalid since they’ll be removed with the parent



30
31
32
33
34
35
36
37
38
# File 'lib/svg_conform/validation_context.rb', line 30

def mark_node_structurally_invalid(node)
  node_id = generate_node_id(node)
  return if node_id.nil? # Safety check

  @structurally_invalid_node_ids.add(node_id)

  # Mark all descendants as invalid too
  mark_descendants_invalid(node)
end

#node_structurally_invalid?(node) ⇒ Boolean

Check if a node is structurally invalid

Returns:

  • (Boolean)


57
58
59
60
61
62
# File 'lib/svg_conform/validation_context.rb', line 57

def node_structurally_invalid?(node)
  node_id = generate_node_id(node)
  return false if node_id.nil? # Safety check

  @structurally_invalid_node_ids.include?(node_id)
end

#register_id(id_value, element_name:, line_number: nil, column_number: nil) ⇒ Object

Register an ID definition



135
136
137
138
139
140
141
142
143
# File 'lib/svg_conform/validation_context.rb', line 135

def register_id(id_value, element_name:, line_number: nil,
column_number: nil)
  @reference_manifest.register_id(
    id_value,
    element_name: element_name,
    line_number: line_number,
    column_number: column_number,
  )
end

#register_reference(reference) ⇒ Object

Register a reference



146
147
148
# File 'lib/svg_conform/validation_context.rb', line 146

def register_reference(reference)
  @reference_manifest.register_reference(reference)
end

#set_data(key, value) ⇒ Object



126
127
128
# File 'lib/svg_conform/validation_context.rb', line 126

def set_data(key, value)
  @data[key] = value
end