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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +182 -21
- data/README.adoc +391 -989
- data/config/profiles/metanorma.yml +5 -0
- data/docs/api_reference.adoc +1355 -0
- data/docs/cli_guide.adoc +846 -0
- data/docs/reference_manifest.adoc +370 -0
- data/docs/requirements.adoc +68 -1
- data/examples/document_input_demo.rb +102 -0
- data/lib/svg_conform/document.rb +40 -1
- data/lib/svg_conform/profile.rb +15 -9
- data/lib/svg_conform/references/base_reference.rb +130 -0
- data/lib/svg_conform/references/id_definition.rb +38 -0
- data/lib/svg_conform/references/reference_classifier.rb +45 -0
- data/lib/svg_conform/references/reference_manifest.rb +129 -0
- data/lib/svg_conform/references.rb +11 -0
- data/lib/svg_conform/remediations/namespace_attribute_remediation.rb +34 -43
- data/lib/svg_conform/requirements/id_collection_requirement.rb +38 -0
- data/lib/svg_conform/requirements/id_reference_requirement.rb +11 -0
- data/lib/svg_conform/requirements/invalid_id_references_requirement.rb +3 -0
- data/lib/svg_conform/requirements/link_validation_requirement.rb +114 -31
- data/lib/svg_conform/requirements/no_external_css_requirement.rb +5 -2
- data/lib/svg_conform/requirements.rb +11 -9
- data/lib/svg_conform/sax_validation_handler.rb +16 -1
- data/lib/svg_conform/validation_context.rb +67 -1
- data/lib/svg_conform/validation_result.rb +43 -2
- data/lib/svg_conform/validator.rb +56 -16
- data/lib/svg_conform/version.rb +1 -1
- data/lib/svg_conform.rb +11 -2
- data/spec/svg_conform/commands/svgcheck_compare_command_spec.rb +1 -0
- data/spec/svg_conform/commands/svgcheck_compatibility_command_spec.rb +1 -0
- data/spec/svg_conform/commands/svgcheck_generate_command_spec.rb +1 -0
- data/spec/svg_conform/references/integration_spec.rb +206 -0
- data/spec/svg_conform/references/reference_classifier_spec.rb +142 -0
- data/spec/svg_conform/references/reference_manifest_spec.rb +307 -0
- data/spec/svg_conform/requirements/id_reference_state_spec.rb +93 -0
- data/spec/svg_conform/validator_input_types_spec.rb +172 -0
- metadata +17 -2
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe "IdReferenceRequirement" do
|
|
6
|
+
let(:validator) { SvgConform::Validator.new(mode: :sax) }
|
|
7
|
+
|
|
8
|
+
# SVG with a reference to undefined ID 'missing_id'
|
|
9
|
+
let(:svg_with_error) do
|
|
10
|
+
<<~SVG
|
|
11
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
12
|
+
<a href="#missing_id">
|
|
13
|
+
<rect x="10" y="10" width="80" height="80"/>
|
|
14
|
+
</a>
|
|
15
|
+
</svg>
|
|
16
|
+
SVG
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# SVG with valid references only
|
|
20
|
+
let(:svg_without_error) do
|
|
21
|
+
<<~SVG
|
|
22
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
23
|
+
<rect id="valid_id" x="10" y="10" width="80" height="80"/>
|
|
24
|
+
<a href="#valid_id">
|
|
25
|
+
<text x="50" y="50">Link</text>
|
|
26
|
+
</a>
|
|
27
|
+
</svg>
|
|
28
|
+
SVG
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "does not leak state from first validation to second validation" do
|
|
32
|
+
# First validation: SVG with reference error
|
|
33
|
+
result1 = validator.validate(svg_with_error, profile: :metanorma)
|
|
34
|
+
|
|
35
|
+
# Verify first validation caught the error
|
|
36
|
+
expect(result1.errors.map(&:message)).to include(
|
|
37
|
+
match(/Reference to undefined ID 'missing_id'/),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Second validation: SVG without reference errors
|
|
41
|
+
result2 = validator.validate(svg_without_error, profile: :metanorma)
|
|
42
|
+
|
|
43
|
+
# Verify second validation does NOT report errors from first validation
|
|
44
|
+
error_messages = result2.errors.map(&:message).join("\n")
|
|
45
|
+
expect(error_messages).not_to include("missing_id"),
|
|
46
|
+
"State leaked from first validation! Second validation should not mention 'missing_id'"
|
|
47
|
+
|
|
48
|
+
# Second validation should have no errors (or at least no reference errors)
|
|
49
|
+
reference_errors = result2.errors.select do |e|
|
|
50
|
+
e.message.include?("Reference to undefined")
|
|
51
|
+
end
|
|
52
|
+
expect(reference_errors).to be_empty,
|
|
53
|
+
"Second validation should have no reference errors, but got: #{reference_errors.map(&:message)}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "handles multiple sequential validations correctly" do
|
|
57
|
+
# Run multiple validations to ensure state resets each time
|
|
58
|
+
results = []
|
|
59
|
+
|
|
60
|
+
# Alternate between error and no-error SVGs
|
|
61
|
+
3.times do
|
|
62
|
+
results << validator.validate(svg_with_error, profile: :metanorma)
|
|
63
|
+
results << validator.validate(svg_without_error, profile: :metanorma)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Check that error pattern is consistent
|
|
67
|
+
results.each_with_index do |result, i|
|
|
68
|
+
if i.even?
|
|
69
|
+
# Should have error (svg_with_error)
|
|
70
|
+
expect(result.errors.map(&:message)).to include(
|
|
71
|
+
match(/Reference to undefined ID 'missing_id'/),
|
|
72
|
+
)
|
|
73
|
+
else
|
|
74
|
+
# Should NOT have error about missing_id (svg_without_error)
|
|
75
|
+
error_messages = result.errors.map(&:message).join("\n")
|
|
76
|
+
expect(error_messages).not_to include("missing_id")
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "resets state when using the same profile instance" do
|
|
82
|
+
# Get profile instance
|
|
83
|
+
profile = SvgConform::Profiles.get(:metanorma)
|
|
84
|
+
|
|
85
|
+
# Run two validations using the same profile
|
|
86
|
+
validator.validate(svg_with_error, profile: profile)
|
|
87
|
+
result2 = validator.validate(svg_without_error, profile: profile)
|
|
88
|
+
|
|
89
|
+
# Second validation should not have first validation's errors
|
|
90
|
+
error_messages = result2.errors.map(&:message).join("\n")
|
|
91
|
+
expect(error_messages).not_to include("missing_id")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe SvgConform::Validator do
|
|
6
|
+
let(:validator) { described_class.new(mode: :sax) }
|
|
7
|
+
let(:simple_svg) do
|
|
8
|
+
<<~SVG
|
|
9
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
10
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
11
|
+
<rect id="box" x="10" y="10" width="80" height="80" fill="black"/>
|
|
12
|
+
</svg>
|
|
13
|
+
SVG
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "#validate with different input types" do
|
|
17
|
+
context "with String input (backward compatibility)" do
|
|
18
|
+
it "validates XML string successfully" do
|
|
19
|
+
result = validator.validate(simple_svg, profile: :metanorma)
|
|
20
|
+
|
|
21
|
+
expect(result).to be_a(SvgConform::ValidationResult)
|
|
22
|
+
expect(result.valid?).to be true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "processes errors correctly" do
|
|
26
|
+
invalid_svg = '<svg><rect fill="red"/></svg>'
|
|
27
|
+
result = validator.validate(invalid_svg, profile: :svg_1_2_rfc)
|
|
28
|
+
|
|
29
|
+
expect(result).to be_a(SvgConform::ValidationResult)
|
|
30
|
+
# Will have errors due to missing viewBox and invalid color
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "with Moxml::Document input" do
|
|
35
|
+
it "validates Moxml document without re-parsing" do
|
|
36
|
+
# Parse once into Moxml
|
|
37
|
+
moxml_doc = Moxml.new.parse(simple_svg)
|
|
38
|
+
|
|
39
|
+
# Validate using the document object
|
|
40
|
+
result = validator.validate(moxml_doc, profile: :metanorma)
|
|
41
|
+
|
|
42
|
+
expect(result).to be_a(SvgConform::ValidationResult)
|
|
43
|
+
expect(result.valid?).to be true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "serializes document once for SAX validation (safe for large files)" do
|
|
47
|
+
moxml_doc = Moxml.new.parse(simple_svg)
|
|
48
|
+
|
|
49
|
+
# Should call to_xml once for SAX validation
|
|
50
|
+
# (SAX mode is safe for large files, unlike DOM)
|
|
51
|
+
expect(moxml_doc).to receive(:to_xml).once.and_call_original
|
|
52
|
+
|
|
53
|
+
validator.validate(moxml_doc, profile: :metanorma)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "with Moxml::Element input" do
|
|
58
|
+
it "validates Moxml element node" do
|
|
59
|
+
moxml_doc = Moxml.new.parse(simple_svg)
|
|
60
|
+
svg_element = moxml_doc.root
|
|
61
|
+
|
|
62
|
+
result = validator.validate(svg_element, profile: :metanorma)
|
|
63
|
+
|
|
64
|
+
expect(result).to be_a(SvgConform::ValidationResult)
|
|
65
|
+
expect(result.valid?).to be true
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "with Nokogiri input (metanorm use case)" do
|
|
70
|
+
it "validates Nokogiri::XML::Document" do
|
|
71
|
+
nokogiri_doc = Nokogiri::XML(simple_svg)
|
|
72
|
+
|
|
73
|
+
result = validator.validate(nokogiri_doc, profile: :metanorma)
|
|
74
|
+
|
|
75
|
+
expect(result).to be_a(SvgConform::ValidationResult)
|
|
76
|
+
expect(result.valid?).to be true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "validates Nokogiri::XML::Element" do
|
|
80
|
+
nokogiri_doc = Nokogiri::XML(simple_svg)
|
|
81
|
+
svg_element = nokogiri_doc.root
|
|
82
|
+
|
|
83
|
+
# This is the metanorma use case - passing element directly
|
|
84
|
+
result = validator.validate(svg_element, profile: :metanorma)
|
|
85
|
+
|
|
86
|
+
expect(result).to be_a(SvgConform::ValidationResult)
|
|
87
|
+
expect(result.valid?).to be true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "serializes Nokogiri element once for SAX validation" do
|
|
91
|
+
nokogiri_doc = Nokogiri::XML(simple_svg)
|
|
92
|
+
svg_element = nokogiri_doc.root
|
|
93
|
+
|
|
94
|
+
# Should call to_xml once for SAX validation
|
|
95
|
+
# (SAX mode is memory-safe for large SVGs)
|
|
96
|
+
expect(svg_element).to receive(:to_xml).once.and_call_original
|
|
97
|
+
|
|
98
|
+
validator.validate(svg_element, profile: :metanorma)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "with invalid input" do
|
|
103
|
+
it "raises ArgumentError for unsupported input type" do
|
|
104
|
+
expect do
|
|
105
|
+
validator.validate(12345, profile: :metanorma)
|
|
106
|
+
end.to raise_error(ArgumentError, /Invalid input type/)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "raises ArgumentError for nil input" do
|
|
110
|
+
expect do
|
|
111
|
+
validator.validate(nil, profile: :metanorma)
|
|
112
|
+
end.to raise_error(ArgumentError, /Invalid input type/)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "with reference manifest" do
|
|
117
|
+
let(:svg_with_refs) do
|
|
118
|
+
<<~SVG
|
|
119
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
120
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
121
|
+
<defs>
|
|
122
|
+
<rect id="box" width="10" height="10"/>
|
|
123
|
+
</defs>
|
|
124
|
+
<use href="#box" x="20" y="20"/>
|
|
125
|
+
</svg>
|
|
126
|
+
SVG
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "builds reference manifest from Nokogiri element" do
|
|
130
|
+
nokogiri_doc = Nokogiri::XML(svg_with_refs)
|
|
131
|
+
svg_element = nokogiri_doc.root
|
|
132
|
+
|
|
133
|
+
result = validator.validate(svg_element, profile: :metanorma)
|
|
134
|
+
|
|
135
|
+
expect(result.reference_manifest).not_to be_nil
|
|
136
|
+
expect(result.available_ids.map(&:id_value)).to include("box")
|
|
137
|
+
expect(result.internal_references.size).to be > 0
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "builds reference manifest from Moxml document" do
|
|
141
|
+
moxml_doc = Moxml.new.parse(svg_with_refs)
|
|
142
|
+
|
|
143
|
+
result = validator.validate(moxml_doc, profile: :metanorma)
|
|
144
|
+
|
|
145
|
+
expect(result.reference_manifest).not_to be_nil
|
|
146
|
+
expect(result.available_ids.map(&:id_value)).to include("box")
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
describe "integration with remediation" do
|
|
152
|
+
let(:invalid_svg) do
|
|
153
|
+
<<~SVG
|
|
154
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
155
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
156
|
+
<rect fill="red" width="10" height="10"/>
|
|
157
|
+
</svg>
|
|
158
|
+
SVG
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "applies remediation when using document object input" do
|
|
162
|
+
nokogiri_doc = Nokogiri::XML(invalid_svg)
|
|
163
|
+
svg_element = nokogiri_doc.root
|
|
164
|
+
|
|
165
|
+
result = validator.validate(svg_element, profile: :svg_1_2_rfc, fix: true)
|
|
166
|
+
|
|
167
|
+
# Should have validation errors initially
|
|
168
|
+
expect(result.has_errors?).to be true
|
|
169
|
+
# Remediation should have been attempted
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: svg_conform
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-11-
|
|
11
|
+
date: 2025-11-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|
|
@@ -92,11 +92,15 @@ files:
|
|
|
92
92
|
- config/profiles/svg_1_2_rfc.yml
|
|
93
93
|
- config/profiles/svg_1_2_rfc_with_rdf.yml
|
|
94
94
|
- config/svgcheck_mapping.yml
|
|
95
|
+
- docs/api_reference.adoc
|
|
96
|
+
- docs/cli_guide.adoc
|
|
95
97
|
- docs/profiles.adoc
|
|
96
98
|
- docs/rdf_metadata_support.adoc
|
|
99
|
+
- docs/reference_manifest.adoc
|
|
97
100
|
- docs/remediation.adoc
|
|
98
101
|
- docs/requirements.adoc
|
|
99
102
|
- examples/demo.rb
|
|
103
|
+
- examples/document_input_demo.rb
|
|
100
104
|
- examples/readme_usage.rb
|
|
101
105
|
- examples/requirements_demo.rb
|
|
102
106
|
- exe/svg_conform
|
|
@@ -137,6 +141,11 @@ files:
|
|
|
137
141
|
- lib/svg_conform/node_index_builder.rb
|
|
138
142
|
- lib/svg_conform/profile.rb
|
|
139
143
|
- lib/svg_conform/profiles.rb
|
|
144
|
+
- lib/svg_conform/references.rb
|
|
145
|
+
- lib/svg_conform/references/base_reference.rb
|
|
146
|
+
- lib/svg_conform/references/id_definition.rb
|
|
147
|
+
- lib/svg_conform/references/reference_classifier.rb
|
|
148
|
+
- lib/svg_conform/references/reference_manifest.rb
|
|
140
149
|
- lib/svg_conform/remediation_engine.rb
|
|
141
150
|
- lib/svg_conform/remediation_result.rb
|
|
142
151
|
- lib/svg_conform/remediation_runner.rb
|
|
@@ -160,6 +169,7 @@ files:
|
|
|
160
169
|
- lib/svg_conform/requirements/element_requirement_config.rb
|
|
161
170
|
- lib/svg_conform/requirements/font_family_requirement.rb
|
|
162
171
|
- lib/svg_conform/requirements/forbidden_content_requirement.rb
|
|
172
|
+
- lib/svg_conform/requirements/id_collection_requirement.rb
|
|
163
173
|
- lib/svg_conform/requirements/id_reference_requirement.rb
|
|
164
174
|
- lib/svg_conform/requirements/invalid_id_references_requirement.rb
|
|
165
175
|
- lib/svg_conform/requirements/link_validation_requirement.rb
|
|
@@ -386,6 +396,9 @@ files:
|
|
|
386
396
|
- spec/svg_conform/profiles/no_external_css_profile_spec.rb
|
|
387
397
|
- spec/svg_conform/profiles/svg_1_2_rfc_profile_spec.rb
|
|
388
398
|
- spec/svg_conform/profiles/svg_1_2_rfc_with_rdf_profile_spec.rb
|
|
399
|
+
- spec/svg_conform/references/integration_spec.rb
|
|
400
|
+
- spec/svg_conform/references/reference_classifier_spec.rb
|
|
401
|
+
- spec/svg_conform/references/reference_manifest_spec.rb
|
|
389
402
|
- spec/svg_conform/remediations/color_remediation_spec.rb
|
|
390
403
|
- spec/svg_conform/remediations/font_embedding_remediation_spec.rb
|
|
391
404
|
- spec/svg_conform/remediations/font_remediation_spec.rb
|
|
@@ -401,6 +414,7 @@ files:
|
|
|
401
414
|
- spec/svg_conform/requirements/font_family_requirement_spec.rb
|
|
402
415
|
- spec/svg_conform/requirements/forbidden_content_requirement_spec.rb
|
|
403
416
|
- spec/svg_conform/requirements/id_reference_requirement_spec.rb
|
|
417
|
+
- spec/svg_conform/requirements/id_reference_state_spec.rb
|
|
404
418
|
- spec/svg_conform/requirements/invalid_id_references_requirement_spec.rb
|
|
405
419
|
- spec/svg_conform/requirements/link_validation_requirement_spec.rb
|
|
406
420
|
- spec/svg_conform/requirements/namespace_attributes_requirement_spec.rb
|
|
@@ -411,6 +425,7 @@ files:
|
|
|
411
425
|
- spec/svg_conform/requirements/style_promotion_requirement_spec.rb
|
|
412
426
|
- spec/svg_conform/requirements/style_requirement_spec.rb
|
|
413
427
|
- spec/svg_conform/requirements/viewbox_required_requirement_spec.rb
|
|
428
|
+
- spec/svg_conform/validator_input_types_spec.rb
|
|
414
429
|
- spec/svg_conform_spec.rb
|
|
415
430
|
- spec/svgcheck_compatibility_spec.rb
|
|
416
431
|
- svg_conform.gemspec
|