svg_conform 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +182 -21
  3. data/README.adoc +391 -989
  4. data/config/profiles/metanorma.yml +5 -0
  5. data/docs/api_reference.adoc +1355 -0
  6. data/docs/cli_guide.adoc +846 -0
  7. data/docs/reference_manifest.adoc +370 -0
  8. data/docs/requirements.adoc +68 -1
  9. data/examples/document_input_demo.rb +102 -0
  10. data/lib/svg_conform/document.rb +40 -1
  11. data/lib/svg_conform/profile.rb +15 -9
  12. data/lib/svg_conform/references/base_reference.rb +130 -0
  13. data/lib/svg_conform/references/id_definition.rb +38 -0
  14. data/lib/svg_conform/references/reference_classifier.rb +45 -0
  15. data/lib/svg_conform/references/reference_manifest.rb +129 -0
  16. data/lib/svg_conform/references.rb +11 -0
  17. data/lib/svg_conform/remediations/namespace_attribute_remediation.rb +34 -43
  18. data/lib/svg_conform/requirements/id_collection_requirement.rb +38 -0
  19. data/lib/svg_conform/requirements/id_reference_requirement.rb +11 -0
  20. data/lib/svg_conform/requirements/invalid_id_references_requirement.rb +3 -0
  21. data/lib/svg_conform/requirements/link_validation_requirement.rb +114 -31
  22. data/lib/svg_conform/requirements/no_external_css_requirement.rb +5 -2
  23. data/lib/svg_conform/requirements.rb +11 -9
  24. data/lib/svg_conform/sax_validation_handler.rb +16 -1
  25. data/lib/svg_conform/validation_context.rb +67 -1
  26. data/lib/svg_conform/validation_result.rb +43 -2
  27. data/lib/svg_conform/validator.rb +56 -16
  28. data/lib/svg_conform/version.rb +1 -1
  29. data/lib/svg_conform.rb +11 -2
  30. data/spec/svg_conform/commands/svgcheck_compare_command_spec.rb +1 -0
  31. data/spec/svg_conform/commands/svgcheck_compatibility_command_spec.rb +1 -0
  32. data/spec/svg_conform/commands/svgcheck_generate_command_spec.rb +1 -0
  33. data/spec/svg_conform/references/integration_spec.rb +206 -0
  34. data/spec/svg_conform/references/reference_classifier_spec.rb +142 -0
  35. data/spec/svg_conform/references/reference_manifest_spec.rb +307 -0
  36. data/spec/svg_conform/requirements/id_reference_state_spec.rb +93 -0
  37. data/spec/svg_conform/validator_input_types_spec.rb +172 -0
  38. metadata +17 -2
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "base_requirement"
4
+ require_relative "../references/reference_classifier"
4
5
 
5
6
  module SvgConform
6
7
  module Requirements
@@ -9,22 +10,26 @@ module SvgConform
9
10
  return unless element?(node)
10
11
 
11
12
  # Check href attributes (both href and xlink:href)
12
- href_value = get_attribute(node, "href")
13
+ href_value = extract_href(node)
14
+ return unless href_value
13
15
 
14
- # Check for xlink:href if regular href is not present
15
- if href_value.nil? && node.respond_to?(:attributes)
16
- xlink_href = node.attributes.find do |attr|
17
- attr.name == "href" && attr.namespace&.uri == "http://www.w3.org/1999/xlink"
18
- end
19
- href_value = xlink_href&.value
20
- end
16
+ # Always validate ASCII requirement (applies to all references)
17
+ validate_ascii(href_value, node, context)
21
18
 
22
- if href_value && !ascii_only?(href_value)
23
- context.add_error(
24
- requirement_id: id,
25
- message: "Link href '#{href_value}' contains non-ASCII characters",
19
+ # Classify and register the reference
20
+ reference = classify_reference(href_value, node)
21
+ return unless reference
22
+
23
+ context.register_reference(reference)
24
+
25
+ # Only validate internal references
26
+ if reference.internally_validatable?
27
+ validate_internal_reference(reference, node, context)
28
+ elsif reference.requires_consumer_validation?
29
+ # Don't error - just notify consumer
30
+ context.add_external_reference_notice(
26
31
  node: node,
27
- severity: :error,
32
+ reference: reference,
28
33
  )
29
34
  end
30
35
 
@@ -34,14 +39,11 @@ module SvgConform
34
39
  iri_value = get_attribute(node, attr_name)
35
40
  next unless iri_value
36
41
 
37
- next if ascii_only?(iri_value)
42
+ validate_ascii_attribute(iri_value, attr_name, node, context)
38
43
 
39
- context.add_error(
40
- requirement_id: id,
41
- message: "IRI attribute '#{attr_name}' value '#{iri_value}' contains non-ASCII characters",
42
- node: node,
43
- severity: :error,
44
- )
44
+ # Classify and register these references too
45
+ iri_ref = classify_reference(iri_value, node, attr_name)
46
+ context.register_reference(iri_ref) if iri_ref
45
47
  end
46
48
  end
47
49
 
@@ -49,13 +51,30 @@ module SvgConform
49
51
  # Check href attributes
50
52
  href_value = element.raw_attributes["href"] || element.raw_attributes["xlink:href"]
51
53
 
52
- if href_value && !ascii_only?(href_value)
53
- context.add_error(
54
- requirement_id: id,
55
- message: "Link href '#{href_value}' contains non-ASCII characters",
56
- node: element,
57
- severity: :error,
54
+ if href_value
55
+ validate_ascii(href_value, element, context)
56
+
57
+ # Classify and register
58
+ reference = References::ReferenceClassifier.classify(
59
+ href_value,
60
+ element_name: element.name,
61
+ attribute_name: "href",
62
+ line_number: element.line,
63
+ column_number: element.column,
58
64
  )
65
+
66
+ if reference
67
+ context.register_reference(reference)
68
+
69
+ if reference.internally_validatable?
70
+ validate_internal_reference(reference, element, context)
71
+ elsif reference.requires_consumer_validation?
72
+ context.add_external_reference_notice(
73
+ node: element,
74
+ reference: reference,
75
+ )
76
+ end
77
+ end
59
78
  end
60
79
 
61
80
  # Check other IRI attributes
@@ -64,19 +83,83 @@ module SvgConform
64
83
  iri_value = element.raw_attributes[attr_name]
65
84
  next unless iri_value
66
85
 
67
- next if ascii_only?(iri_value)
86
+ validate_ascii_attribute(iri_value, attr_name, element, context)
68
87
 
88
+ # Classify and register
89
+ iri_ref = References::ReferenceClassifier.classify(
90
+ iri_value,
91
+ element_name: element.name,
92
+ attribute_name: attr_name,
93
+ line_number: element.line,
94
+ column_number: element.column,
95
+ )
96
+ context.register_reference(iri_ref) if iri_ref
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ def extract_href(node)
103
+ href_value = get_attribute(node, "href")
104
+ return href_value if href_value
105
+
106
+ # Check for xlink:href if regular href is not present
107
+ if node.respond_to?(:attributes)
108
+ xlink_href = node.attributes.find do |attr|
109
+ attr.name == "href" && attr.namespace&.uri == "http://www.w3.org/1999/xlink"
110
+ end
111
+ xlink_href&.value
112
+ end
113
+ end
114
+
115
+ def classify_reference(href_value, node, attr_name = "href")
116
+ References::ReferenceClassifier.classify(
117
+ href_value,
118
+ element_name: node.name,
119
+ attribute_name: attr_name,
120
+ line_number: node.respond_to?(:line) ? node.line : nil,
121
+ column_number: node.respond_to?(:column) ? node.column : nil,
122
+ )
123
+ end
124
+
125
+ def validate_ascii(href_value, node, context)
126
+ return if ascii_only?(href_value)
127
+
128
+ context.add_error(
129
+ requirement_id: id,
130
+ message: "Link href '#{href_value}' contains non-ASCII characters",
131
+ node: node,
132
+ severity: :error,
133
+ )
134
+ end
135
+
136
+ def validate_ascii_attribute(iri_value, attr_name, node, context)
137
+ return if ascii_only?(iri_value)
138
+
139
+ context.add_error(
140
+ requirement_id: id,
141
+ message: "IRI attribute '#{attr_name}' value '#{iri_value}' contains non-ASCII characters",
142
+ node: node,
143
+ severity: :error,
144
+ )
145
+ end
146
+
147
+ def validate_internal_reference(reference, node, context)
148
+ return unless reference.is_a?(References::InternalFragmentReference)
149
+
150
+ target_id = reference.target_id
151
+
152
+ # Use manifest to check if ID exists
153
+ unless context.id_defined?(target_id)
69
154
  context.add_error(
70
155
  requirement_id: id,
71
- message: "IRI attribute '#{attr_name}' value '#{iri_value}' contains non-ASCII characters",
72
- node: element,
156
+ message: "Internal reference '#{reference.value}' points to non-existent element",
157
+ node: node,
73
158
  severity: :error,
74
159
  )
75
160
  end
76
161
  end
77
162
 
78
- private
79
-
80
163
  def ascii_only?(string)
81
164
  string.ascii_only?
82
165
  end
@@ -41,10 +41,10 @@ module SvgConform
41
41
  end
42
42
 
43
43
  def needs_deferred_validation?
44
- check_style_elements # Only deferred if checking style elements
44
+ check_style_elements # Only deferred if checking style elements
45
45
  end
46
46
 
47
- def collect_sax_data(element, context)
47
+ def collect_sax_data(element, _context)
48
48
  # Collect style elements for deferred validation (text content needs to be complete)
49
49
  if check_style_elements && element.name == "style"
50
50
  @collected_style_elements << element
@@ -52,6 +52,9 @@ module SvgConform
52
52
  end
53
53
 
54
54
  def validate_sax_complete(context)
55
+ # Guard against nil collection
56
+ return unless @collected_style_elements
57
+
55
58
  # Validate collected style elements
56
59
  @collected_style_elements.each do |element|
57
60
  check_style_element_sax(element, context)
@@ -1,21 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "requirements/base_requirement"
4
+ require_relative "requirements/element_requirement_config"
4
5
  require_relative "requirements/allowed_elements_requirement"
5
- require_relative "requirements/color_restrictions_requirement"
6
- require_relative "requirements/font_family_requirement"
7
- require_relative "requirements/invalid_id_references_requirement"
8
6
  require_relative "requirements/namespace_requirement"
9
- require_relative "requirements/no_external_css_requirement"
10
- require_relative "requirements/no_external_fonts_requirement"
11
- require_relative "requirements/no_external_images_requirement"
12
- require_relative "requirements/viewbox_required_requirement"
13
7
  require_relative "requirements/namespace_attributes_requirement"
8
+ require_relative "requirements/viewbox_required_requirement"
9
+ require_relative "requirements/link_validation_requirement"
10
+ require_relative "requirements/id_reference_requirement"
11
+ require_relative "requirements/id_collection_requirement"
12
+ require_relative "requirements/invalid_id_references_requirement"
14
13
  require_relative "requirements/forbidden_content_requirement"
14
+ require_relative "requirements/color_restrictions_requirement"
15
+ require_relative "requirements/font_family_requirement"
15
16
  require_relative "requirements/style_requirement"
16
17
  require_relative "requirements/style_promotion_requirement"
17
- require_relative "requirements/link_validation_requirement"
18
- require_relative "requirements/id_reference_requirement"
18
+ require_relative "requirements/no_external_css_requirement"
19
+ require_relative "requirements/no_external_fonts_requirement"
20
+ require_relative "requirements/no_external_images_requirement"
19
21
 
20
22
  module SvgConform
21
23
  module Requirements
@@ -4,6 +4,7 @@ require "nokogiri"
4
4
  require_relative "element_proxy"
5
5
  require_relative "validation_context"
6
6
  require_relative "validation_result"
7
+ require_relative "references"
7
8
 
8
9
  module SvgConform
9
10
  # SAX event handler for streaming SVG validation
@@ -30,6 +31,9 @@ module SvgConform
30
31
 
31
32
  # SAX Event: Document start
32
33
  def start_document
34
+ # Reset state in requirements that maintain state across validations
35
+ reset_stateful_requirements
36
+
33
37
  # Initialize root level counters
34
38
  @position_counters.push({})
35
39
  end
@@ -143,12 +147,14 @@ module SvgConform
143
147
  context.instance_variable_set(:@structurally_invalid_node_ids, Set.new)
144
148
  context.instance_variable_set(:@node_id_cache, {})
145
149
  context.instance_variable_set(:@cache_populated, true) # Skip population for SAX
150
+ context.instance_variable_set(:@reference_manifest,
151
+ References::ReferenceManifest.new(source_document: nil))
146
152
  context
147
153
  end
148
154
 
149
155
  # Classify requirements based on validation needs
150
156
  def classify_requirements
151
- return unless @profile.requirements
157
+ return unless @profile&.requirements
152
158
 
153
159
  @profile.requirements.each do |req|
154
160
  if req.respond_to?(:needs_deferred_validation?) && req.needs_deferred_validation?
@@ -158,5 +164,14 @@ module SvgConform
158
164
  end
159
165
  end
160
166
  end
167
+
168
+ # Reset state in requirements that maintain state
169
+ def reset_stateful_requirements
170
+ return unless @profile&.requirements
171
+
172
+ @profile.requirements.each do |req|
173
+ req.reset_state if req.respond_to?(:reset_state)
174
+ end
175
+ end
161
176
  end
162
177
  end
@@ -6,7 +6,7 @@ module SvgConform
6
6
  # Context object passed to rules during validation
7
7
  class ValidationContext
8
8
  attr_reader :document, :profile, :errors, :warnings, :fixes,
9
- :validity_errors
9
+ :validity_errors, :reference_manifest
10
10
 
11
11
  def initialize(document, profile)
12
12
  @document = document
@@ -19,6 +19,9 @@ module SvgConform
19
19
  @structurally_invalid_node_ids = Set.new
20
20
  @node_id_cache = {}
21
21
  @cache_populated = false
22
+ @reference_manifest = References::ReferenceManifest.new(
23
+ source_document: document.file_path,
24
+ )
22
25
  end
23
26
 
24
27
  # Mark a node as structurally invalid (e.g., invalid parent-child relationship)
@@ -128,6 +131,39 @@ requirement_id: nil, severity: nil, fix: nil, data: {})
128
131
  @data[key]
129
132
  end
130
133
 
134
+ # Register an ID definition
135
+ def register_id(id_value, element_name:, line_number: nil,
136
+ column_number: nil)
137
+ @reference_manifest.register_id(
138
+ id_value,
139
+ element_name: element_name,
140
+ line_number: line_number,
141
+ column_number: column_number,
142
+ )
143
+ end
144
+
145
+ # Register a reference
146
+ def register_reference(reference)
147
+ @reference_manifest.register_reference(reference)
148
+ end
149
+
150
+ # Check if ID exists in manifest
151
+ def id_defined?(id_value)
152
+ @reference_manifest.id_defined?(id_value)
153
+ end
154
+
155
+ # Add notice for external references (not errors)
156
+ def add_external_reference_notice(node:, reference:, message: nil)
157
+ notice = ValidationNotice.new(
158
+ type: :external_reference,
159
+ node: node,
160
+ message: message || "External reference: #{reference.value}",
161
+ data: { reference: reference },
162
+ )
163
+ @infos << notice
164
+ notice
165
+ end
166
+
131
167
  # Generate a unique identifier for a node based on its path
132
168
  # Builds a stable path by walking up the parent chain
133
169
  # OPTIMIZED: Lazy cache population - populate entire cache on first call
@@ -489,4 +525,34 @@ requirement_id: nil, severity: nil, violation_type: nil)
489
525
  end
490
526
  end
491
527
  end
528
+
529
+ # New class for non-error notifications
530
+ class ValidationNotice
531
+ attr_reader :type, :node, :message, :data
532
+
533
+ def initialize(type:, node:, message:, data: {})
534
+ @type = type
535
+ @node = node
536
+ @message = message
537
+ @data = data
538
+ end
539
+
540
+ def line
541
+ @node.respond_to?(:line) ? @node.line : nil
542
+ end
543
+
544
+ def column
545
+ @node.respond_to?(:column) ? @node.column : nil
546
+ end
547
+
548
+ def to_h
549
+ {
550
+ type: @type,
551
+ message: @message,
552
+ line: line,
553
+ column: column,
554
+ data: @data,
555
+ }
556
+ end
557
+ end
492
558
  end
@@ -6,7 +6,7 @@ module SvgConform
6
6
  # Represents the result of validating an SVG document
7
7
  class ValidationResult
8
8
  attr_reader :document, :profile, :errors, :warnings, :validity_errors,
9
- :fixes_applied, :fixed_document
9
+ :fixes_applied, :fixed_document, :reference_manifest
10
10
 
11
11
  def initialize(document, profile, context)
12
12
  @document = document
@@ -16,6 +16,7 @@ module SvgConform
16
16
  @validity_errors = context.validity_errors
17
17
  @fixes_applied = []
18
18
  @fixed_document = nil
19
+ @reference_manifest = context.reference_manifest
19
20
  end
20
21
 
21
22
  def valid?
@@ -58,6 +59,31 @@ module SvgConform
58
59
  @errors.select(&:requirement_id)
59
60
  end
60
61
 
62
+ # Convenience accessors for manifest data
63
+ def available_ids
64
+ @reference_manifest.available_ids
65
+ end
66
+
67
+ def internal_references
68
+ @reference_manifest.internal_references
69
+ end
70
+
71
+ def external_references
72
+ @reference_manifest.external_references
73
+ end
74
+
75
+ def has_external_references?
76
+ !@reference_manifest.external_references.empty?
77
+ end
78
+
79
+ def unresolved_internal_references
80
+ @reference_manifest.unresolved_internal_references
81
+ end
82
+
83
+ def reference_statistics
84
+ @reference_manifest.statistics
85
+ end
86
+
61
87
  def apply_fixes
62
88
  return self unless fixable?
63
89
 
@@ -90,13 +116,14 @@ module SvgConform
90
116
 
91
117
  def to_h
92
118
  {
93
- file: @document.file_path,
119
+ file: @document&.file_path,
94
120
  profile: @profile.name,
95
121
  valid: valid?,
96
122
  errors: @errors.map(&:to_h),
97
123
  warnings: @warnings.map(&:to_h),
98
124
  fixes_applied: @fixes_applied.size,
99
125
  fixable: fixable_count,
126
+ reference_manifest: @reference_manifest.to_h,
100
127
  }
101
128
  end
102
129
 
@@ -104,6 +131,20 @@ module SvgConform
104
131
  JSON.pretty_generate(to_h, *args)
105
132
  end
106
133
 
134
+ # Export manifest separately for detailed analysis
135
+ def export_manifest(format: :yaml)
136
+ case format
137
+ when :yaml
138
+ @reference_manifest.to_yaml
139
+ when :json
140
+ @reference_manifest.to_json
141
+ when :hash
142
+ @reference_manifest.to_h
143
+ else
144
+ @reference_manifest.to_yaml
145
+ end
146
+ end
147
+
107
148
  private
108
149
 
109
150
  def to_text
@@ -31,25 +31,23 @@ module SvgConform
31
31
  end
32
32
  end
33
33
 
34
- # Validate SVG content string
35
- def validate(svg_content, profile: :svg_1_2_rfc, **options)
34
+ # Validate SVG content string or document object
35
+ # Accepts:
36
+ # - String (XML content) → uses SAX for efficient parsing
37
+ # - Moxml::Document or Moxml::Element → serializes once, then SAX validates
38
+ # - Nokogiri::XML::Document or Nokogiri::XML::Element → serializes once, then SAX validates
39
+ # - Any adapter document object (Ox, Oga, REXML, LibXML) → serializes once, then SAX validates
40
+ #
41
+ # IMPORTANT: Always uses SAX validation to safely handle large SVG files.
42
+ # DOM validation can hang on large files, so we serialize once and validate with SAX.
43
+ def validate(input, profile: :svg_1_2_rfc, **options)
36
44
  merged_options = @options.merge(options)
37
- mode = merged_options[:mode]
38
45
 
39
- # Default to SAX if not specified
40
- mode = :sax if mode.nil?
46
+ # Normalize input to string, then use SAX validation
47
+ svg_content = normalize_input_to_string(input)
41
48
 
42
- case mode
43
- when :sax
44
- validate_content_sax(svg_content, profile: profile, **merged_options)
45
- when :dom
46
- validate_content_dom(svg_content, profile: profile, **merged_options)
47
- when :auto
48
- # For content, we can't check file size, so default to SAX
49
- validate_content_sax(svg_content, profile: profile, **merged_options)
50
- else
51
- validate_content_sax(svg_content, profile: profile, **merged_options)
52
- end
49
+ # Always use SAX mode for safe validation (handles large files)
50
+ validate_content_sax(svg_content, profile: profile, **merged_options)
53
51
  end
54
52
 
55
53
  # Validate a Document object (DOM only)
@@ -87,6 +85,48 @@ module SvgConform
87
85
 
88
86
  private
89
87
 
88
+ # Normalize various input types to XML string
89
+ def normalize_input_to_string(input)
90
+ case input
91
+ when String
92
+ # Already a string, return as-is
93
+ input
94
+ else
95
+ # Try to detect and convert document objects
96
+ convert_document_to_string(input)
97
+ end
98
+ end
99
+
100
+ # Convert document object to XML string
101
+ def convert_document_to_string(input)
102
+ # Check for Moxml document or element
103
+ if input.respond_to?(:to_xml)
104
+ return input.to_xml
105
+ end
106
+
107
+ # Check for Nokogiri document or element
108
+ if defined?(Nokogiri) && input.is_a?(Nokogiri::XML::Node)
109
+ return input.to_xml
110
+ end
111
+
112
+ # Check for other adapter documents that respond to to_xml
113
+ if input.respond_to?(:to_s) && xml_like?(input)
114
+ return input.to_s
115
+ end
116
+
117
+ # If we can't convert, raise an error
118
+ raise ArgumentError,
119
+ "Invalid input type: #{input.class}. " \
120
+ "Expected String, Moxml document, Nokogiri document, or adapter document object. " \
121
+ "Input must respond to #to_xml or be a valid XML string."
122
+ end
123
+
124
+ # Check if object looks like an XML document
125
+ def xml_like?(obj)
126
+ # Basic heuristic: check if it has XML-like methods
127
+ obj.respond_to?(:name) && obj.respond_to?(:children)
128
+ end
129
+
90
130
  def determine_mode(file_path, requested_mode)
91
131
  case requested_mode
92
132
  when :sax
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SvgConform
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
data/lib/svg_conform.rb CHANGED
@@ -10,16 +10,25 @@ Lutaml::Model::Config.configure do |config|
10
10
  end
11
11
 
12
12
  require_relative "svg_conform/version"
13
+ require_relative "svg_conform/constants"
14
+ require_relative "svg_conform/profile"
15
+ require_relative "svg_conform/profiles"
13
16
  require_relative "svg_conform/document"
14
17
  require_relative "svg_conform/sax_document"
18
+ require_relative "svg_conform/element_proxy"
15
19
  require_relative "svg_conform/validation_context"
16
20
  require_relative "svg_conform/validation_result"
17
- require_relative "svg_conform/profiles"
21
+ require_relative "svg_conform/validator"
22
+ require_relative "svg_conform/conformance_report"
23
+ require_relative "svg_conform/batch_report"
18
24
  require_relative "svg_conform/requirements"
25
+ require_relative "svg_conform/references"
19
26
  require_relative "svg_conform/remediations"
20
27
  require_relative "svg_conform/remediation_result"
28
+ require_relative "svg_conform/remediation_engine"
29
+ require_relative "svg_conform/remediation_runner"
30
+ require_relative "svg_conform/fixer"
21
31
  require_relative "svg_conform/external_checkers"
22
- require_relative "svg_conform/cli"
23
32
 
24
33
  module SvgConform
25
34
  class Error < StandardError; end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require "svg_conform/commands/svgcheck_compare"
4
5
 
5
6
  RSpec.describe SvgConform::Commands::SvgcheckCompare do
6
7
  describe "#execute" do
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require "svg_conform/commands/svgcheck_compatibility"
4
5
 
5
6
  RSpec.describe SvgConform::Commands::SvgcheckCompatibility do
6
7
  describe "#execute" do
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
+ require "svg_conform/commands/svgcheck_generate"
4
5
 
5
6
  RSpec.describe SvgConform::Commands::SvgcheckGenerate do
6
7
  describe "#execute" do