svg_conform 0.1.0

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 (335) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/rake.yml +15 -0
  3. data/.github/workflows/release.yml +23 -0
  4. data/.github/workflows/svgcheck-compatibility.yml +135 -0
  5. data/.gitignore +12 -0
  6. data/.rspec +3 -0
  7. data/.rubocop.yml +13 -0
  8. data/.rubocop_todo.yml +183 -0
  9. data/CODE_OF_CONDUCT.md +132 -0
  10. data/Gemfile +14 -0
  11. data/README.adoc +1384 -0
  12. data/Rakefile +15 -0
  13. data/config/profiles/base.yml +34 -0
  14. data/config/profiles/lucid_fix.yml +37 -0
  15. data/config/profiles/metanorma.yml +212 -0
  16. data/config/profiles/no_external_css.yml +20 -0
  17. data/config/profiles/svg_1_2_rfc.yml +284 -0
  18. data/config/profiles/svg_1_2_rfc_with_rdf.yml +145 -0
  19. data/config/svgcheck_mapping.yml +180 -0
  20. data/docs/profiles.adoc +547 -0
  21. data/docs/rdf_metadata_support.adoc +212 -0
  22. data/docs/remediation.adoc +732 -0
  23. data/docs/requirements.adoc +709 -0
  24. data/examples/demo.rb +116 -0
  25. data/examples/requirements_demo.rb +240 -0
  26. data/exe/svg_conform +7 -0
  27. data/lib/svg_conform/batch_report.rb +70 -0
  28. data/lib/svg_conform/cli.rb +107 -0
  29. data/lib/svg_conform/commands/check.rb +390 -0
  30. data/lib/svg_conform/commands/profiles.rb +118 -0
  31. data/lib/svg_conform/commands/svgcheck.rb +90 -0
  32. data/lib/svg_conform/commands/svgcheck_compare.rb +92 -0
  33. data/lib/svg_conform/commands/svgcheck_compatibility.rb +43 -0
  34. data/lib/svg_conform/commands/svgcheck_generate.rb +262 -0
  35. data/lib/svg_conform/compatibility/analysis_context.rb +68 -0
  36. data/lib/svg_conform/compatibility/comparison_result.rb +147 -0
  37. data/lib/svg_conform/compatibility/compatibility_analyzer.rb +85 -0
  38. data/lib/svg_conform/compatibility/file_processor.rb +109 -0
  39. data/lib/svg_conform/compatibility/pattern_discovery.rb +319 -0
  40. data/lib/svg_conform/compatibility/report_formatter.rb +359 -0
  41. data/lib/svg_conform/compatibility/svg_analysis_engine.rb +316 -0
  42. data/lib/svg_conform/compatibility/validity_analysis.rb +252 -0
  43. data/lib/svg_conform/compatibility/xml_analysis_engine.rb +198 -0
  44. data/lib/svg_conform/compatibility_analyzer.rb +285 -0
  45. data/lib/svg_conform/conformance_report.rb +267 -0
  46. data/lib/svg_conform/constants.rb +199 -0
  47. data/lib/svg_conform/css_color.rb +262 -0
  48. data/lib/svg_conform/document.rb +203 -0
  49. data/lib/svg_conform/external_checkers/svgcheck/compatibility_engine.rb +166 -0
  50. data/lib/svg_conform/external_checkers/svgcheck/output_generator.rb +101 -0
  51. data/lib/svg_conform/external_checkers/svgcheck/parser.rb +200 -0
  52. data/lib/svg_conform/external_checkers/svgcheck/report_comparator.rb +175 -0
  53. data/lib/svg_conform/external_checkers/svgcheck/report_generator.rb +82 -0
  54. data/lib/svg_conform/external_checkers/svgcheck/validation_pipeline.rb +249 -0
  55. data/lib/svg_conform/external_checkers/svgcheck.rb +56 -0
  56. data/lib/svg_conform/external_checkers.rb +34 -0
  57. data/lib/svg_conform/fixer.rb +56 -0
  58. data/lib/svg_conform/profile.rb +164 -0
  59. data/lib/svg_conform/profiles.rb +60 -0
  60. data/lib/svg_conform/remediation_engine.rb +92 -0
  61. data/lib/svg_conform/remediation_result.rb +36 -0
  62. data/lib/svg_conform/remediation_runner.rb +225 -0
  63. data/lib/svg_conform/remediations/base_remediation.rb +165 -0
  64. data/lib/svg_conform/remediations/color_remediation.rb +226 -0
  65. data/lib/svg_conform/remediations/font_embedding_remediation.rb +145 -0
  66. data/lib/svg_conform/remediations/font_remediation.rb +122 -0
  67. data/lib/svg_conform/remediations/image_embedding_remediation.rb +154 -0
  68. data/lib/svg_conform/remediations/invalid_id_references_remediation.rb +129 -0
  69. data/lib/svg_conform/remediations/namespace_attribute_remediation.rb +244 -0
  70. data/lib/svg_conform/remediations/namespace_remediation.rb +151 -0
  71. data/lib/svg_conform/remediations/no_external_css_remediation.rb +192 -0
  72. data/lib/svg_conform/remediations/style_promotion_remediation.rb +93 -0
  73. data/lib/svg_conform/remediations/viewbox_remediation.rb +127 -0
  74. data/lib/svg_conform/remediations.rb +40 -0
  75. data/lib/svg_conform/report_comparator.rb +772 -0
  76. data/lib/svg_conform/requirements/allowed_elements_requirement.rb +367 -0
  77. data/lib/svg_conform/requirements/base_requirement.rb +98 -0
  78. data/lib/svg_conform/requirements/color_restrictions_requirement.rb +126 -0
  79. data/lib/svg_conform/requirements/element_requirement_config.rb +75 -0
  80. data/lib/svg_conform/requirements/font_family_requirement.rb +133 -0
  81. data/lib/svg_conform/requirements/forbidden_content_requirement.rb +60 -0
  82. data/lib/svg_conform/requirements/id_reference_requirement.rb +133 -0
  83. data/lib/svg_conform/requirements/invalid_id_references_requirement.rb +132 -0
  84. data/lib/svg_conform/requirements/link_validation_requirement.rb +55 -0
  85. data/lib/svg_conform/requirements/namespace_attributes_requirement.rb +211 -0
  86. data/lib/svg_conform/requirements/namespace_requirement.rb +294 -0
  87. data/lib/svg_conform/requirements/no_external_css_requirement.rb +132 -0
  88. data/lib/svg_conform/requirements/no_external_fonts_requirement.rb +121 -0
  89. data/lib/svg_conform/requirements/no_external_images_requirement.rb +91 -0
  90. data/lib/svg_conform/requirements/style_promotion_requirement.rb +72 -0
  91. data/lib/svg_conform/requirements/style_requirement.rb +226 -0
  92. data/lib/svg_conform/requirements/viewbox_required_requirement.rb +96 -0
  93. data/lib/svg_conform/requirements.rb +49 -0
  94. data/lib/svg_conform/semantic_comparator.rb +829 -0
  95. data/lib/svg_conform/validation_context.rb +408 -0
  96. data/lib/svg_conform/validation_result.rb +146 -0
  97. data/lib/svg_conform/validator.rb +91 -0
  98. data/lib/svg_conform/version.rb +5 -0
  99. data/lib/svg_conform.rb +68 -0
  100. data/lib/tasks/fixtures.rake +321 -0
  101. data/lib/tasks/svgcheck.rake +111 -0
  102. data/reference-docs/SVG-1.2-RFC.rnc.txt +1676 -0
  103. data/reference-docs/Scalable Vector Graphics (SVG) 1.1 (Second Edition).html +40764 -0
  104. data/reference-docs/Scalable Vector Graphics (SVG) Tiny 1.2 Specification.html +44591 -0
  105. data/reference-docs/rfc7996.txt +2971 -0
  106. data/sig/svg_conform.rbs +4 -0
  107. data/spec/fixtures/allowed_elements/inputs/basic_violations.svg +21 -0
  108. data/spec/fixtures/allowed_elements/repair/basic_violations.svg +18 -0
  109. data/spec/fixtures/color_restrictions/inputs/basic_violations.svg +23 -0
  110. data/spec/fixtures/color_restrictions/repair/basic_violations.svg +23 -0
  111. data/spec/fixtures/comprehensive/inputs/multiple_violations.svg +21 -0
  112. data/spec/fixtures/comprehensive/repair/multiple_violations.svg +16 -0
  113. data/spec/fixtures/font_family/inputs/basic_violations.svg +17 -0
  114. data/spec/fixtures/font_family/repair/basic_violations.svg +17 -0
  115. data/spec/fixtures/forbidden_content/inputs/basic_violations.svg +27 -0
  116. data/spec/fixtures/forbidden_content/repair/basic_violations.svg +19 -0
  117. data/spec/fixtures/id_reference/inputs/basic_violations.svg +17 -0
  118. data/spec/fixtures/id_reference/repair/basic_violations.svg +15 -0
  119. data/spec/fixtures/link_validation/inputs/basic_violations.svg +20 -0
  120. data/spec/fixtures/link_validation/repair/basic_violations.svg +16 -0
  121. data/spec/fixtures/lucid/inputs/simple.svg +67 -0
  122. data/spec/fixtures/lucid/repair/simple.svg +63 -0
  123. data/spec/fixtures/namespace/inputs/basic_violations.svg +20 -0
  124. data/spec/fixtures/namespace/repair/basic_violations.svg +17 -0
  125. data/spec/fixtures/namespace_attributes/inputs/basic_violations.svg +16 -0
  126. data/spec/fixtures/namespace_attributes/repair/basic_violations.svg +15 -0
  127. data/spec/fixtures/no_external_css/inputs/basic_violations.svg +20 -0
  128. data/spec/fixtures/no_external_css/repair/basic_violations.svg +18 -0
  129. data/spec/fixtures/style/inputs/basic_violations.svg +22 -0
  130. data/spec/fixtures/style/repair/basic_violations.svg +22 -0
  131. data/spec/fixtures/style_promotion/inputs/basic_test.svg +15 -0
  132. data/spec/fixtures/style_promotion/repair/basic_test.svg +15 -0
  133. data/spec/fixtures/svg_1_2_rfc/inputs/allowed_elements_violations.svg +18 -0
  134. data/spec/fixtures/svg_1_2_rfc/inputs/color_restrictions_violations.svg +23 -0
  135. data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.code +1 -0
  136. data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.err +0 -0
  137. data/spec/fixtures/svgcheck/check/DrawBerry-sample-2.svg.out +23 -0
  138. data/spec/fixtures/svgcheck/check/IETF-test.svg.code +1 -0
  139. data/spec/fixtures/svgcheck/check/IETF-test.svg.err +0 -0
  140. data/spec/fixtures/svgcheck/check/IETF-test.svg.out +20 -0
  141. data/spec/fixtures/svgcheck/check/circle.svg.code +1 -0
  142. data/spec/fixtures/svgcheck/check/circle.svg.err +0 -0
  143. data/spec/fixtures/svgcheck/check/circle.svg.out +2 -0
  144. data/spec/fixtures/svgcheck/check/colors.svg.code +1 -0
  145. data/spec/fixtures/svgcheck/check/colors.svg.err +0 -0
  146. data/spec/fixtures/svgcheck/check/colors.svg.out +13 -0
  147. data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.code +1 -0
  148. data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.err +0 -0
  149. data/spec/fixtures/svgcheck/check/dia-sample-svg.svg.out +76 -0
  150. data/spec/fixtures/svgcheck/check/example-dot.svg.code +1 -0
  151. data/spec/fixtures/svgcheck/check/example-dot.svg.err +0 -0
  152. data/spec/fixtures/svgcheck/check/example-dot.svg.out +11 -0
  153. data/spec/fixtures/svgcheck/check/full-tiny.svg.code +1 -0
  154. data/spec/fixtures/svgcheck/check/full-tiny.svg.err +0 -0
  155. data/spec/fixtures/svgcheck/check/full-tiny.svg.out +5835 -0
  156. data/spec/fixtures/svgcheck/check/good.svg.code +1 -0
  157. data/spec/fixtures/svgcheck/check/good.svg.err +0 -0
  158. data/spec/fixtures/svgcheck/check/good.svg.out +1 -0
  159. data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.code +1 -0
  160. data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.err +0 -0
  161. data/spec/fixtures/svgcheck/check/httpbis-proxy20-fig6.svg.out +5 -0
  162. data/spec/fixtures/svgcheck/check/malformed.svg.code +1 -0
  163. data/spec/fixtures/svgcheck/check/malformed.svg.err +0 -0
  164. data/spec/fixtures/svgcheck/check/malformed.svg.out +8 -0
  165. data/spec/fixtures/svgcheck/check/rfc-svg.svg.code +1 -0
  166. data/spec/fixtures/svgcheck/check/rfc-svg.svg.err +0 -0
  167. data/spec/fixtures/svgcheck/check/rfc-svg.svg.out +1 -0
  168. data/spec/fixtures/svgcheck/check/rfc.xml.code +1 -0
  169. data/spec/fixtures/svgcheck/check/rfc.xml.err +0 -0
  170. data/spec/fixtures/svgcheck/check/rfc.xml.out +2 -0
  171. data/spec/fixtures/svgcheck/check/rgb.svg.code +1 -0
  172. data/spec/fixtures/svgcheck/check/rgb.svg.err +0 -0
  173. data/spec/fixtures/svgcheck/check/rgb.svg.out +9 -0
  174. data/spec/fixtures/svgcheck/check/svg-wordle.svg.code +1 -0
  175. data/spec/fixtures/svgcheck/check/svg-wordle.svg.err +0 -0
  176. data/spec/fixtures/svgcheck/check/svg-wordle.svg.out +508 -0
  177. data/spec/fixtures/svgcheck/check/threshold.svg.code +1 -0
  178. data/spec/fixtures/svgcheck/check/threshold.svg.err +0 -0
  179. data/spec/fixtures/svgcheck/check/threshold.svg.out +20 -0
  180. data/spec/fixtures/svgcheck/check/utf8.svg.code +1 -0
  181. data/spec/fixtures/svgcheck/check/utf8.svg.err +0 -0
  182. data/spec/fixtures/svgcheck/check/utf8.svg.out +162 -0
  183. data/spec/fixtures/svgcheck/check/viewBox-both.svg.code +1 -0
  184. data/spec/fixtures/svgcheck/check/viewBox-both.svg.err +0 -0
  185. data/spec/fixtures/svgcheck/check/viewBox-both.svg.out +4 -0
  186. data/spec/fixtures/svgcheck/check/viewBox-height.svg.code +1 -0
  187. data/spec/fixtures/svgcheck/check/viewBox-height.svg.err +0 -0
  188. data/spec/fixtures/svgcheck/check/viewBox-height.svg.out +3 -0
  189. data/spec/fixtures/svgcheck/check/viewBox-none.svg.code +1 -0
  190. data/spec/fixtures/svgcheck/check/viewBox-none.svg.err +0 -0
  191. data/spec/fixtures/svgcheck/check/viewBox-none.svg.out +3 -0
  192. data/spec/fixtures/svgcheck/check/viewBox-width.svg.code +1 -0
  193. data/spec/fixtures/svgcheck/check/viewBox-width.svg.err +0 -0
  194. data/spec/fixtures/svgcheck/check/viewBox-width.svg.out +3 -0
  195. data/spec/fixtures/svgcheck/inputs/DrawBerry-sample-2.svg +28 -0
  196. data/spec/fixtures/svgcheck/inputs/IETF-test.svg +28 -0
  197. data/spec/fixtures/svgcheck/inputs/circle.svg +3 -0
  198. data/spec/fixtures/svgcheck/inputs/colors.svg +18 -0
  199. data/spec/fixtures/svgcheck/inputs/dia-sample-svg.svg +47 -0
  200. data/spec/fixtures/svgcheck/inputs/example-dot.svg +75 -0
  201. data/spec/fixtures/svgcheck/inputs/full-tiny.svg +16194 -0
  202. data/spec/fixtures/svgcheck/inputs/good.svg +19 -0
  203. data/spec/fixtures/svgcheck/inputs/httpbis-proxy20-fig6.svg +2 -0
  204. data/spec/fixtures/svgcheck/inputs/malformed.svg +11 -0
  205. data/spec/fixtures/svgcheck/inputs/rfc-svg.svg +1028 -0
  206. data/spec/fixtures/svgcheck/inputs/rfc.xml +37 -0
  207. data/spec/fixtures/svgcheck/inputs/rgb.svg +9 -0
  208. data/spec/fixtures/svgcheck/inputs/svg-wordle.svg +330 -0
  209. data/spec/fixtures/svgcheck/inputs/threshold.svg +26 -0
  210. data/spec/fixtures/svgcheck/inputs/utf8.svg +448 -0
  211. data/spec/fixtures/svgcheck/inputs/viewBox-both.svg +3 -0
  212. data/spec/fixtures/svgcheck/inputs/viewBox-height.svg +3 -0
  213. data/spec/fixtures/svgcheck/inputs/viewBox-none.svg +3 -0
  214. data/spec/fixtures/svgcheck/inputs/viewBox-width.svg +3 -0
  215. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.code +1 -0
  216. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.err +0 -0
  217. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.file +0 -0
  218. data/spec/fixtures/svgcheck/repair/DrawBerry-sample-2.svg.out +23 -0
  219. data/spec/fixtures/svgcheck/repair/IETF-test.svg.code +1 -0
  220. data/spec/fixtures/svgcheck/repair/IETF-test.svg.err +0 -0
  221. data/spec/fixtures/svgcheck/repair/IETF-test.svg.file +29 -0
  222. data/spec/fixtures/svgcheck/repair/IETF-test.svg.out +20 -0
  223. data/spec/fixtures/svgcheck/repair/circle.svg.code +1 -0
  224. data/spec/fixtures/svgcheck/repair/circle.svg.err +0 -0
  225. data/spec/fixtures/svgcheck/repair/circle.svg.file +4 -0
  226. data/spec/fixtures/svgcheck/repair/circle.svg.out +2 -0
  227. data/spec/fixtures/svgcheck/repair/colors.svg.code +1 -0
  228. data/spec/fixtures/svgcheck/repair/colors.svg.err +0 -0
  229. data/spec/fixtures/svgcheck/repair/colors.svg.file +19 -0
  230. data/spec/fixtures/svgcheck/repair/colors.svg.out +13 -0
  231. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.code +1 -0
  232. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.err +0 -0
  233. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.file +47 -0
  234. data/spec/fixtures/svgcheck/repair/dia-sample-svg.svg.out +76 -0
  235. data/spec/fixtures/svgcheck/repair/example-dot.svg.code +1 -0
  236. data/spec/fixtures/svgcheck/repair/example-dot.svg.err +0 -0
  237. data/spec/fixtures/svgcheck/repair/example-dot.svg.file +69 -0
  238. data/spec/fixtures/svgcheck/repair/example-dot.svg.out +11 -0
  239. data/spec/fixtures/svgcheck/repair/good.svg.code +1 -0
  240. data/spec/fixtures/svgcheck/repair/good.svg.err +0 -0
  241. data/spec/fixtures/svgcheck/repair/good.svg.file +0 -0
  242. data/spec/fixtures/svgcheck/repair/good.svg.out +1 -0
  243. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.code +1 -0
  244. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.err +0 -0
  245. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.file +73 -0
  246. data/spec/fixtures/svgcheck/repair/httpbis-proxy20-fig6.svg.out +5 -0
  247. data/spec/fixtures/svgcheck/repair/malformed.svg.code +1 -0
  248. data/spec/fixtures/svgcheck/repair/malformed.svg.err +0 -0
  249. data/spec/fixtures/svgcheck/repair/malformed.svg.file +9 -0
  250. data/spec/fixtures/svgcheck/repair/malformed.svg.out +8 -0
  251. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.code +1 -0
  252. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.err +0 -0
  253. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.file +0 -0
  254. data/spec/fixtures/svgcheck/repair/rfc-svg.svg.out +1 -0
  255. data/spec/fixtures/svgcheck/repair/rfc.xml.code +1 -0
  256. data/spec/fixtures/svgcheck/repair/rfc.xml.err +0 -0
  257. data/spec/fixtures/svgcheck/repair/rfc.xml.file +37 -0
  258. data/spec/fixtures/svgcheck/repair/rfc.xml.out +2 -0
  259. data/spec/fixtures/svgcheck/repair/rgb.svg.code +1 -0
  260. data/spec/fixtures/svgcheck/repair/rgb.svg.err +0 -0
  261. data/spec/fixtures/svgcheck/repair/rgb.svg.file +10 -0
  262. data/spec/fixtures/svgcheck/repair/rgb.svg.out +9 -0
  263. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.code +1 -0
  264. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.err +0 -0
  265. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.file +112 -0
  266. data/spec/fixtures/svgcheck/repair/svg-wordle.svg.out +508 -0
  267. data/spec/fixtures/svgcheck/repair/threshold.svg.code +1 -0
  268. data/spec/fixtures/svgcheck/repair/threshold.svg.err +0 -0
  269. data/spec/fixtures/svgcheck/repair/threshold.svg.file +27 -0
  270. data/spec/fixtures/svgcheck/repair/threshold.svg.out +20 -0
  271. data/spec/fixtures/svgcheck/repair/utf8.svg.code +1 -0
  272. data/spec/fixtures/svgcheck/repair/utf8.svg.err +0 -0
  273. data/spec/fixtures/svgcheck/repair/utf8.svg.file +381 -0
  274. data/spec/fixtures/svgcheck/repair/utf8.svg.out +162 -0
  275. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.code +1 -0
  276. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.err +0 -0
  277. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.file +4 -0
  278. data/spec/fixtures/svgcheck/repair/viewBox-both.svg.out +4 -0
  279. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.code +1 -0
  280. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.err +0 -0
  281. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.file +4 -0
  282. data/spec/fixtures/svgcheck/repair/viewBox-height.svg.out +3 -0
  283. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.code +1 -0
  284. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.err +0 -0
  285. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.file +4 -0
  286. data/spec/fixtures/svgcheck/repair/viewBox-none.svg.out +3 -0
  287. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.code +1 -0
  288. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.err +0 -0
  289. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.file +4 -0
  290. data/spec/fixtures/svgcheck/repair/viewBox-width.svg.out +3 -0
  291. data/spec/fixtures/viewbox_required/inputs/missing_viewbox.svg +10 -0
  292. data/spec/fixtures/viewbox_required/repair/missing_viewbox.svg +10 -0
  293. data/spec/spec_helper.rb +16 -0
  294. data/spec/svg_conform/batch_report_spec.rb +99 -0
  295. data/spec/svg_conform/commands/check_command_spec.rb +90 -0
  296. data/spec/svg_conform/commands/profiles_command_spec.rb +20 -0
  297. data/spec/svg_conform/commands/svgcheck_compare_command_spec.rb +13 -0
  298. data/spec/svg_conform/commands/svgcheck_compatibility_command_spec.rb +13 -0
  299. data/spec/svg_conform/commands/svgcheck_generate_command_spec.rb +14 -0
  300. data/spec/svg_conform/profiles/base_profile_spec.rb +42 -0
  301. data/spec/svg_conform/profiles/lucid_fix_profile_spec.rb +46 -0
  302. data/spec/svg_conform/profiles/lucid_profile_spec.rb +84 -0
  303. data/spec/svg_conform/profiles/metanorma_profile_spec.rb +62 -0
  304. data/spec/svg_conform/profiles/no_external_css_profile_spec.rb +66 -0
  305. data/spec/svg_conform/profiles/svg_1_2_rfc_profile_spec.rb +200 -0
  306. data/spec/svg_conform/profiles/svg_1_2_rfc_with_rdf_profile_spec.rb +81 -0
  307. data/spec/svg_conform/remediations/color_remediation_spec.rb +95 -0
  308. data/spec/svg_conform/remediations/font_embedding_remediation_spec.rb +20 -0
  309. data/spec/svg_conform/remediations/font_remediation_spec.rb +95 -0
  310. data/spec/svg_conform/remediations/image_embedding_remediation_spec.rb +20 -0
  311. data/spec/svg_conform/remediations/invalid_id_references_remediation_spec.rb +97 -0
  312. data/spec/svg_conform/remediations/namespace_attribute_remediation_spec.rb +97 -0
  313. data/spec/svg_conform/remediations/namespace_remediation_spec.rb +95 -0
  314. data/spec/svg_conform/remediations/no_external_css_remediation_spec.rb +97 -0
  315. data/spec/svg_conform/remediations/style_promotion_remediation_spec.rb +97 -0
  316. data/spec/svg_conform/remediations/viewbox_remediation_spec.rb +95 -0
  317. data/spec/svg_conform/requirements/allowed_elements_requirement_spec.rb +118 -0
  318. data/spec/svg_conform/requirements/color_restrictions_requirement_spec.rb +168 -0
  319. data/spec/svg_conform/requirements/font_family_requirement_spec.rb +188 -0
  320. data/spec/svg_conform/requirements/forbidden_content_requirement_spec.rb +195 -0
  321. data/spec/svg_conform/requirements/id_reference_requirement_spec.rb +78 -0
  322. data/spec/svg_conform/requirements/invalid_id_references_requirement_spec.rb +78 -0
  323. data/spec/svg_conform/requirements/link_validation_requirement_spec.rb +78 -0
  324. data/spec/svg_conform/requirements/namespace_attributes_requirement_spec.rb +86 -0
  325. data/spec/svg_conform/requirements/namespace_requirement_spec.rb +184 -0
  326. data/spec/svg_conform/requirements/no_external_css_requirement_spec.rb +78 -0
  327. data/spec/svg_conform/requirements/no_external_fonts_requirement_spec.rb +20 -0
  328. data/spec/svg_conform/requirements/no_external_images_requirement_spec.rb +20 -0
  329. data/spec/svg_conform/requirements/style_promotion_requirement_spec.rb +78 -0
  330. data/spec/svg_conform/requirements/style_requirement_spec.rb +76 -0
  331. data/spec/svg_conform/requirements/viewbox_required_requirement_spec.rb +165 -0
  332. data/spec/svg_conform_spec.rb +32 -0
  333. data/spec/svgcheck_compatibility_spec.rb +355 -0
  334. data/svg_conform.gemspec +35 -0
  335. metadata +436 -0
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Requirements::InvalidIdReferencesRequirement do
7
+ let(:fixtures_dir) { "spec/fixtures/invalid_id_references" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/invalid_id_references/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/invalid_id_references/repair/#{basename}")
13
+ end.map do |f|
14
+ File.basename(f, ".svg")
15
+ end
16
+
17
+ fixture_files.each do |fixture_name|
18
+ describe "fixture: #{fixture_name}" do
19
+ let(:input_file) do
20
+ "spec/fixtures/invalid_id_references/inputs/#{fixture_name}.svg"
21
+ end
22
+ let(:expected_output_file) do
23
+ "spec/fixtures/invalid_id_references/repair/#{fixture_name}.svg"
24
+ end
25
+
26
+ it "validates input file and identifies violations" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+
29
+ document = SvgConform::Document.from_file(input_file)
30
+ requirement = described_class.new(
31
+ id: "invalid_id_references",
32
+ description: "Test invalid id references requirement",
33
+ )
34
+
35
+ context = SvgConform::ValidationContext.new(document, nil)
36
+ requirement.validate_document(document, context)
37
+
38
+ expect(context.errors).not_to be_empty
39
+ puts "Found #{context.errors.count} invalid id references violations in #{fixture_name}"
40
+
41
+ context.errors.each do |error|
42
+ expect(error.requirement_id).to eq("invalid_id_references")
43
+ expect(error.message).to be_a(String)
44
+ expect(error.message).not_to be_empty
45
+ end
46
+ end
47
+
48
+ it "correctly identifies specific violations" do
49
+ skip "Input file not found" unless File.exist?(input_file)
50
+
51
+ document = SvgConform::Document.from_file(input_file)
52
+ requirement = described_class.new(
53
+ id: "invalid_id_references",
54
+ description: "Test invalid id references requirement",
55
+ )
56
+
57
+ context = SvgConform::ValidationContext.new(document, nil)
58
+ requirement.validate_document(document, context)
59
+
60
+ # Check that errors are relevant to this requirement
61
+ context.errors.each do |error|
62
+ expect(error.message).not_to be_empty
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "configuration" do
69
+ it "can be instantiated with basic parameters" do
70
+ requirement = described_class.new(
71
+ id: "test_invalid_id_references",
72
+ description: "Test requirement",
73
+ )
74
+
75
+ expect(requirement).to be_a(described_class)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Requirements::LinkValidationRequirement do
7
+ let(:fixtures_dir) { "spec/fixtures/link_validation" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/link_validation/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/link_validation/repair/#{basename}")
13
+ end.map do |f|
14
+ File.basename(f, ".svg")
15
+ end
16
+
17
+ fixture_files.each do |fixture_name|
18
+ describe "fixture: #{fixture_name}" do
19
+ let(:input_file) do
20
+ "spec/fixtures/link_validation/inputs/#{fixture_name}.svg"
21
+ end
22
+ let(:expected_output_file) do
23
+ "spec/fixtures/link_validation/repair/#{fixture_name}.svg"
24
+ end
25
+
26
+ it "validates input file and identifies violations" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+
29
+ document = SvgConform::Document.from_file(input_file)
30
+ requirement = described_class.new(
31
+ id: "link_validation",
32
+ description: "Test link validation requirement",
33
+ )
34
+
35
+ context = SvgConform::ValidationContext.new(document, nil)
36
+ requirement.validate_document(document, context)
37
+
38
+ expect(context.errors).not_to be_empty
39
+ puts "Found #{context.errors.count} link validation violations in #{fixture_name}"
40
+
41
+ context.errors.each do |error|
42
+ expect(error.requirement_id).to eq("link_validation")
43
+ expect(error.message).to be_a(String)
44
+ expect(error.message).not_to be_empty
45
+ end
46
+ end
47
+
48
+ it "correctly identifies specific violations" do
49
+ skip "Input file not found" unless File.exist?(input_file)
50
+
51
+ document = SvgConform::Document.from_file(input_file)
52
+ requirement = described_class.new(
53
+ id: "link_validation",
54
+ description: "Test link validation requirement",
55
+ )
56
+
57
+ context = SvgConform::ValidationContext.new(document, nil)
58
+ requirement.validate_document(document, context)
59
+
60
+ # Check that errors are relevant to this requirement
61
+ context.errors.each do |error|
62
+ expect(error.message).not_to be_empty
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "configuration" do
69
+ it "can be instantiated with basic parameters" do
70
+ requirement = described_class.new(
71
+ id: "test_link_validation",
72
+ description: "Test requirement",
73
+ )
74
+
75
+ expect(requirement).to be_a(described_class)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Requirements::NamespaceAttributesRequirement do
7
+ let(:fixtures_dir) { "spec/fixtures/namespace_attributes" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/namespace_attributes/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/namespace_attributes/repair/#{basename}")
13
+ end.map do |f|
14
+ File.basename(f, ".svg")
15
+ end
16
+
17
+ fixture_files.each do |fixture_name|
18
+ describe "fixture: #{fixture_name}" do
19
+ let(:input_file) do
20
+ "spec/fixtures/namespace_attributes/inputs/#{fixture_name}.svg"
21
+ end
22
+ let(:expected_output_file) do
23
+ "spec/fixtures/namespace_attributes/repair/#{fixture_name}.svg"
24
+ end
25
+
26
+ it "validates input file and identifies violations" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+
29
+ document = SvgConform::Document.from_file(input_file)
30
+ requirement = described_class.new(
31
+ id: "namespace_attributes",
32
+ description: "Test namespace attributes requirement",
33
+ disallowed_namespaces: [
34
+ "http://custom.namespace.com",
35
+ "http://www.inkscape.org/namespaces/inkscape",
36
+ ],
37
+ )
38
+
39
+ context = SvgConform::ValidationContext.new(document, nil)
40
+ requirement.validate_document(document, context)
41
+
42
+ expect(context.errors).not_to be_empty
43
+ puts "Found #{context.errors.count} namespace attributes violations in #{fixture_name}"
44
+
45
+ context.errors.each do |error|
46
+ expect(error.requirement_id).to eq("namespace_attributes")
47
+ expect(error.message).to be_a(String)
48
+ expect(error.message).not_to be_empty
49
+ end
50
+ end
51
+
52
+ it "correctly identifies specific violations" do
53
+ skip "Input file not found" unless File.exist?(input_file)
54
+
55
+ document = SvgConform::Document.from_file(input_file)
56
+ requirement = described_class.new(
57
+ id: "namespace_attributes",
58
+ description: "Test namespace attributes requirement",
59
+ disallowed_namespaces: [
60
+ "http://custom.namespace.com",
61
+ "http://www.inkscape.org/namespaces/inkscape",
62
+ ],
63
+ )
64
+
65
+ context = SvgConform::ValidationContext.new(document, nil)
66
+ requirement.validate_document(document, context)
67
+
68
+ # Check that errors are relevant to this requirement
69
+ context.errors.each do |error|
70
+ expect(error.message).not_to be_empty
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "configuration" do
77
+ it "can be instantiated with basic parameters" do
78
+ requirement = described_class.new(
79
+ id: "test_namespace_attributes",
80
+ description: "Test requirement",
81
+ )
82
+
83
+ expect(requirement).to be_a(described_class)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Requirements::NamespaceRequirement do
7
+ let(:fixtures_dir) { "spec/fixtures/namespace" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/namespace/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/namespace/repair/#{basename}")
13
+ end.map do |f|
14
+ File.basename(f, ".svg")
15
+ end
16
+
17
+ fixture_files.each do |fixture_name|
18
+ describe "fixture: #{fixture_name}" do
19
+ let(:input_file) { "spec/fixtures/namespace/inputs/#{fixture_name}.svg" }
20
+ let(:expected_output_file) do
21
+ "spec/fixtures/namespace/repair/#{fixture_name}.svg"
22
+ end
23
+
24
+ it "validates input file and identifies namespace violations" do
25
+ skip "Input file not found" unless File.exist?(input_file)
26
+
27
+ document = SvgConform::Document.from_file(input_file)
28
+ requirement = described_class.new(
29
+ id: "namespace",
30
+ description: "Test namespace requirement",
31
+ required_namespace: "http://www.w3.org/2000/svg",
32
+ )
33
+
34
+ result = context = SvgConform::ValidationContext.new(document, nil)
35
+ requirement.validate_document(document, result)
36
+
37
+ expect(context.errors).not_to be_empty
38
+ puts "Found #{context.errors.count} namespace violations in #{fixture_name}"
39
+
40
+ context.errors.each do |error|
41
+ expect(error.requirement_id).to eq("namespace")
42
+ expect(error.message).to be_a(String)
43
+ expect(error.message).not_to be_empty
44
+ end
45
+ end
46
+
47
+ it "correctly identifies specific namespace violations" do
48
+ skip "Input file not found" unless File.exist?(input_file)
49
+
50
+ document = SvgConform::Document.from_file(input_file)
51
+ requirement = described_class.new(
52
+ id: "namespace",
53
+ description: "Test namespace requirement",
54
+ required_namespace: "http://www.w3.org/2000/svg",
55
+ )
56
+
57
+ result = context = SvgConform::ValidationContext.new(document, nil)
58
+ requirement.validate_document(document, result)
59
+
60
+ # Check that errors are specific to namespace issues
61
+ context.errors.each do |error|
62
+ expect(error.message).to match(/namespace|xmlns/i)
63
+ end
64
+ end
65
+
66
+ it "passes validation for documents with correct namespace" do
67
+ # Create a simple valid document for testing
68
+ valid_svg = <<~SVG
69
+ <?xml version="1.0"?>
70
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
71
+ <rect x="10" y="10" width="20" height="20" fill="black"/>
72
+ </svg>
73
+ SVG
74
+
75
+ document = SvgConform::Document.from_content(valid_svg)
76
+ requirement = described_class.new(
77
+ id: "namespace",
78
+ description: "Test namespace requirement",
79
+ required_namespace: "http://www.w3.org/2000/svg",
80
+ )
81
+
82
+ result = context = SvgConform::ValidationContext.new(document, nil)
83
+ requirement.validate_document(document, result)
84
+
85
+ expect(context.errors).to be_empty
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "configuration" do
91
+ it "accepts custom required namespace" do
92
+ requirement = described_class.new(
93
+ id: "test_namespace",
94
+ description: "Test with custom namespace",
95
+ required_namespace: "http://custom.namespace.com",
96
+ )
97
+
98
+ expect(requirement.instance_variable_get(:@required_namespace)).to eq("http://custom.namespace.com")
99
+ end
100
+
101
+ it "has default required namespace" do
102
+ requirement = described_class.new(
103
+ id: "test_namespace",
104
+ description: "Test requirement",
105
+ )
106
+
107
+ expect(requirement.instance_variable_get(:@required_namespace)).to eq("http://www.w3.org/2000/svg")
108
+ end
109
+ end
110
+
111
+ describe "namespace validation logic" do
112
+ let(:requirement) do
113
+ described_class.new(
114
+ id: "test_namespace",
115
+ description: "Test namespace requirement",
116
+ required_namespace: "http://www.w3.org/2000/svg",
117
+ )
118
+ end
119
+
120
+ it "detects missing namespace on root SVG element" do
121
+ invalid_svg = <<~SVG
122
+ <?xml version="1.0"?>
123
+ <svg viewBox="0 0 100 100">
124
+ <rect x="10" y="10" width="20" height="20" fill="black"/>
125
+ </svg>
126
+ SVG
127
+
128
+ document = SvgConform::Document.from_content(invalid_svg)
129
+ result = context = SvgConform::ValidationContext.new(document, nil)
130
+ requirement.validate_document(document, result)
131
+
132
+ expect(context.errors).not_to be_empty
133
+ expect(context.errors.first.message).to match(/namespace/i)
134
+ end
135
+
136
+ it "detects incorrect namespace on root SVG element" do
137
+ invalid_svg = <<~SVG
138
+ <?xml version="1.0"?>
139
+ <svg xmlns="http://wrong.namespace.com" viewBox="0 0 100 100">
140
+ <rect x="10" y="10" width="20" height="20" fill="black"/>
141
+ </svg>
142
+ SVG
143
+
144
+ document = SvgConform::Document.from_content(invalid_svg)
145
+ result = context = SvgConform::ValidationContext.new(document, nil)
146
+ requirement.validate_document(document, result)
147
+
148
+ expect(context.errors).not_to be_empty
149
+ expect(context.errors.first.message).to match(/namespace/i)
150
+ end
151
+
152
+ it "accepts correct namespace" do
153
+ valid_svg = <<~SVG
154
+ <?xml version="1.0"?>
155
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
156
+ <rect x="10" y="10" width="20" height="20" fill="black"/>
157
+ </svg>
158
+ SVG
159
+
160
+ document = SvgConform::Document.from_content(valid_svg)
161
+ result = context = SvgConform::ValidationContext.new(document, nil)
162
+ requirement.validate_document(document, result)
163
+
164
+ expect(context.errors).to be_empty
165
+ end
166
+
167
+ it "validates elements in wrong namespace" do
168
+ invalid_svg = <<~SVG
169
+ <?xml version="1.0"?>
170
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
171
+ <custom:element xmlns:custom="http://custom.namespace.com"/>
172
+ <rect x="10" y="10" width="20" height="20" fill="black"/>
173
+ </svg>
174
+ SVG
175
+
176
+ document = SvgConform::Document.from_content(invalid_svg)
177
+ result = context = SvgConform::ValidationContext.new(document, nil)
178
+ requirement.validate_document(document, result)
179
+
180
+ expect(context.errors).not_to be_empty
181
+ expect(context.errors.first.message).to match(/namespace.*not permitted/i)
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Requirements::NoExternalCssRequirement do
7
+ let(:fixtures_dir) { "spec/fixtures/no_external_css" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/no_external_css/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/no_external_css/repair/#{basename}")
13
+ end.map do |f|
14
+ File.basename(f, ".svg")
15
+ end
16
+
17
+ fixture_files.each do |fixture_name|
18
+ describe "fixture: #{fixture_name}" do
19
+ let(:input_file) do
20
+ "spec/fixtures/no_external_css/inputs/#{fixture_name}.svg"
21
+ end
22
+ let(:expected_output_file) do
23
+ "spec/fixtures/no_external_css/repair/#{fixture_name}.svg"
24
+ end
25
+
26
+ it "validates input file and identifies violations" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+
29
+ document = SvgConform::Document.from_file(input_file)
30
+ requirement = described_class.new(
31
+ id: "no_external_css",
32
+ description: "Test no external css requirement",
33
+ )
34
+
35
+ context = SvgConform::ValidationContext.new(document, nil)
36
+ requirement.validate_document(document, context)
37
+
38
+ expect(context.errors).not_to be_empty
39
+ puts "Found #{context.errors.count} no external css violations in #{fixture_name}"
40
+
41
+ context.errors.each do |error|
42
+ expect(error.requirement_id).to eq("no_external_css")
43
+ expect(error.message).to be_a(String)
44
+ expect(error.message).not_to be_empty
45
+ end
46
+ end
47
+
48
+ it "correctly identifies specific violations" do
49
+ skip "Input file not found" unless File.exist?(input_file)
50
+
51
+ document = SvgConform::Document.from_file(input_file)
52
+ requirement = described_class.new(
53
+ id: "no_external_css",
54
+ description: "Test no external css requirement",
55
+ )
56
+
57
+ context = SvgConform::ValidationContext.new(document, nil)
58
+ requirement.validate_document(document, context)
59
+
60
+ # Check that errors are relevant to this requirement
61
+ context.errors.each do |error|
62
+ expect(error.message).not_to be_empty
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "configuration" do
69
+ it "can be instantiated with basic parameters" do
70
+ requirement = described_class.new(
71
+ id: "test_no_external_css",
72
+ description: "Test requirement",
73
+ )
74
+
75
+ expect(requirement).to be_a(described_class)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe SvgConform::Requirements::NoExternalFontsRequirement do
6
+ describe "configuration" do
7
+ it "can be instantiated with basic parameters" do
8
+ requirement = described_class.new(
9
+ id: "no_external_fonts",
10
+ description: "Test",
11
+ )
12
+ expect(requirement).to respond_to(:check)
13
+ end
14
+
15
+ it "responds to check method" do
16
+ requirement = described_class.new(id: "test", description: "Test")
17
+ expect(requirement).to respond_to(:check)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe SvgConform::Requirements::NoExternalImagesRequirement do
6
+ describe "configuration" do
7
+ it "can be instantiated with basic parameters" do
8
+ requirement = described_class.new(
9
+ id: "no_external_images",
10
+ description: "Test",
11
+ )
12
+ expect(requirement).to respond_to(:check)
13
+ end
14
+
15
+ it "responds to check method" do
16
+ requirement = described_class.new(id: "test", description: "Test")
17
+ expect(requirement).to respond_to(:check)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Requirements::StylePromotionRequirement do
7
+ let(:fixtures_dir) { "spec/fixtures/style_promotion" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/style_promotion/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/style_promotion/repair/#{basename}")
13
+ end.map do |f|
14
+ File.basename(f, ".svg")
15
+ end
16
+
17
+ fixture_files.each do |fixture_name|
18
+ describe "fixture: #{fixture_name}" do
19
+ let(:input_file) do
20
+ "spec/fixtures/style_promotion/inputs/#{fixture_name}.svg"
21
+ end
22
+ let(:expected_output_file) do
23
+ "spec/fixtures/style_promotion/repair/#{fixture_name}.svg"
24
+ end
25
+
26
+ it "validates input file and identifies violations" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+
29
+ document = SvgConform::Document.from_file(input_file)
30
+ requirement = described_class.new(
31
+ id: "style_promotion",
32
+ description: "Test style promotion requirement",
33
+ )
34
+
35
+ context = SvgConform::ValidationContext.new(document, nil)
36
+ requirement.validate_document(document, context)
37
+
38
+ expect(context.errors).not_to be_empty
39
+ puts "Found #{context.errors.count} style promotion violations in #{fixture_name}"
40
+
41
+ context.errors.each do |error|
42
+ expect(error.requirement_id).to eq("style_promotion")
43
+ expect(error.message).to be_a(String)
44
+ expect(error.message).not_to be_empty
45
+ end
46
+ end
47
+
48
+ it "correctly identifies specific violations" do
49
+ skip "Input file not found" unless File.exist?(input_file)
50
+
51
+ document = SvgConform::Document.from_file(input_file)
52
+ requirement = described_class.new(
53
+ id: "style_promotion",
54
+ description: "Test style promotion requirement",
55
+ )
56
+
57
+ context = SvgConform::ValidationContext.new(document, nil)
58
+ requirement.validate_document(document, context)
59
+
60
+ # Check that errors are relevant to this requirement
61
+ context.errors.each do |error|
62
+ expect(error.message).not_to be_empty
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "configuration" do
69
+ it "can be instantiated with basic parameters" do
70
+ requirement = described_class.new(
71
+ id: "test_style_promotion",
72
+ description: "Test requirement",
73
+ )
74
+
75
+ expect(requirement).to be_a(described_class)
76
+ end
77
+ end
78
+ end