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,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Remediations::NamespaceAttributeRemediation do
7
+ let(:fixtures_dir) { "spec/fixtures/namespace_attribute" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/namespace_attribute/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/namespace_attribute/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_attribute/inputs/#{fixture_name}.svg"
21
+ end
22
+ let(:expected_output_file) do
23
+ "spec/fixtures/namespace_attribute/repair/#{fixture_name}.svg"
24
+ end
25
+
26
+ it "applies remediation and produces expected output" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+ skip "Expected output file not found" unless File.exist?(expected_output_file)
29
+
30
+ document = SvgConform::Document.from_file(input_file)
31
+ remediation = described_class.new(
32
+ id: "namespace_attribute_fix",
33
+ description: "Test namespace attribute remediation",
34
+ )
35
+
36
+ # Apply the remediation
37
+ context = SvgConform::ValidationContext.new(document, nil)
38
+ changes = remediation.apply(document, context)
39
+
40
+ # Verify changes were made
41
+ expect(changes).to be_an(Array)
42
+ puts "Applied #{changes.count} changes in #{fixture_name}" if changes.any?
43
+
44
+ # Get the remediated XML
45
+ actual_xml = document.to_xml
46
+ expected_xml = File.read(expected_output_file)
47
+
48
+ # Use canon matcher for XML equivalence
49
+ expect(actual_xml).to be_analogous_with(expected_xml)
50
+ end
51
+
52
+ it "produces valid XML after remediation" do
53
+ skip "Input file not found" unless File.exist?(input_file)
54
+
55
+ document = SvgConform::Document.from_file(input_file)
56
+ remediation = described_class.new(
57
+ id: "namespace_attribute_fix",
58
+ description: "Test namespace attribute remediation",
59
+ )
60
+
61
+ # Apply the remediation
62
+ context = SvgConform::ValidationContext.new(document, nil)
63
+ remediation.apply(document, context)
64
+
65
+ # Get the remediated XML
66
+ actual_xml = document.to_xml
67
+
68
+ # Basic XML validity check
69
+ expect(actual_xml).to include("<svg")
70
+ expect(actual_xml).to include("</svg>")
71
+ expect do
72
+ SvgConform::Document.from_content(actual_xml)
73
+ end.not_to raise_error
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "configuration" do
79
+ it "can be instantiated with basic parameters" do
80
+ remediation = described_class.new(
81
+ id: "test_namespace_attribute_fix",
82
+ description: "Test remediation",
83
+ )
84
+
85
+ expect(remediation).to be_a(described_class)
86
+ end
87
+
88
+ it "responds to apply method" do
89
+ remediation = described_class.new(
90
+ id: "test_namespace_attribute_fix",
91
+ description: "Test remediation",
92
+ )
93
+
94
+ expect(remediation).to respond_to(:apply)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Remediations::NamespaceRemediation 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 "applies remediation and produces expected output" do
25
+ skip "Input file not found" unless File.exist?(input_file)
26
+ skip "Expected output file not found" unless File.exist?(expected_output_file)
27
+
28
+ document = SvgConform::Document.from_file(input_file)
29
+ remediation = described_class.new(
30
+ id: "namespace_fix",
31
+ description: "Test namespace remediation",
32
+ )
33
+
34
+ # Apply the remediation
35
+ context = SvgConform::ValidationContext.new(document, nil)
36
+ changes = remediation.apply(document, context)
37
+
38
+ # Verify changes were made
39
+ expect(changes).to be_an(Array)
40
+ puts "Applied #{changes.count} changes in #{fixture_name}" if changes.any?
41
+
42
+ # Get the remediated XML
43
+ actual_xml = document.to_xml
44
+ expected_xml = File.read(expected_output_file)
45
+
46
+ # Use canon matcher for XML equivalence
47
+ expect(actual_xml).to be_analogous_with(expected_xml)
48
+ end
49
+
50
+ it "produces valid XML after remediation" do
51
+ skip "Input file not found" unless File.exist?(input_file)
52
+
53
+ document = SvgConform::Document.from_file(input_file)
54
+ remediation = described_class.new(
55
+ id: "namespace_fix",
56
+ description: "Test namespace remediation",
57
+ )
58
+
59
+ # Apply the remediation
60
+ context = SvgConform::ValidationContext.new(document, nil)
61
+ remediation.apply(document, context)
62
+
63
+ # Get the remediated XML
64
+ actual_xml = document.to_xml
65
+
66
+ # Basic XML validity check
67
+ expect(actual_xml).to include("<svg")
68
+ expect(actual_xml).to include("</svg>")
69
+ expect do
70
+ SvgConform::Document.from_content(actual_xml)
71
+ end.not_to raise_error
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "configuration" do
77
+ it "can be instantiated with basic parameters" do
78
+ remediation = described_class.new(
79
+ id: "test_namespace_fix",
80
+ description: "Test remediation",
81
+ )
82
+
83
+ expect(remediation).to be_a(described_class)
84
+ end
85
+
86
+ it "responds to apply method" do
87
+ remediation = described_class.new(
88
+ id: "test_namespace_fix",
89
+ description: "Test remediation",
90
+ )
91
+
92
+ expect(remediation).to respond_to(:apply)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Remediations::NoExternalCssRemediation 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 "applies remediation and produces expected output" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+ skip "Expected output file not found" unless File.exist?(expected_output_file)
29
+
30
+ document = SvgConform::Document.from_file(input_file)
31
+ remediation = described_class.new(
32
+ id: "no_external_css_fix",
33
+ description: "Test no external css remediation",
34
+ )
35
+
36
+ # Apply the remediation
37
+ context = SvgConform::ValidationContext.new(document, nil)
38
+ changes = remediation.apply(document, context)
39
+
40
+ # Verify changes were made
41
+ expect(changes).to be_an(Array)
42
+ puts "Applied #{changes.count} changes in #{fixture_name}" if changes.any?
43
+
44
+ # Get the remediated XML
45
+ actual_xml = document.to_xml
46
+ expected_xml = File.read(expected_output_file)
47
+
48
+ # Use canon matcher for XML equivalence
49
+ expect(actual_xml).to be_analogous_with(expected_xml)
50
+ end
51
+
52
+ it "produces valid XML after remediation" do
53
+ skip "Input file not found" unless File.exist?(input_file)
54
+
55
+ document = SvgConform::Document.from_file(input_file)
56
+ remediation = described_class.new(
57
+ id: "no_external_css_fix",
58
+ description: "Test no external css remediation",
59
+ )
60
+
61
+ # Apply the remediation
62
+ context = SvgConform::ValidationContext.new(document, nil)
63
+ remediation.apply(document, context)
64
+
65
+ # Get the remediated XML
66
+ actual_xml = document.to_xml
67
+
68
+ # Basic XML validity check
69
+ expect(actual_xml).to include("<svg")
70
+ expect(actual_xml).to include("</svg>")
71
+ expect do
72
+ SvgConform::Document.from_content(actual_xml)
73
+ end.not_to raise_error
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "configuration" do
79
+ it "can be instantiated with basic parameters" do
80
+ remediation = described_class.new(
81
+ id: "test_no_external_css_fix",
82
+ description: "Test remediation",
83
+ )
84
+
85
+ expect(remediation).to be_a(described_class)
86
+ end
87
+
88
+ it "responds to apply method" do
89
+ remediation = described_class.new(
90
+ id: "test_no_external_css_fix",
91
+ description: "Test remediation",
92
+ )
93
+
94
+ expect(remediation).to respond_to(:apply)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Remediations::StylePromotionRemediation 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 "applies remediation and produces expected output" do
27
+ skip "Input file not found" unless File.exist?(input_file)
28
+ skip "Expected output file not found" unless File.exist?(expected_output_file)
29
+
30
+ document = SvgConform::Document.from_file(input_file)
31
+ remediation = described_class.new(
32
+ id: "style_promotion_fix",
33
+ description: "Test style promotion remediation",
34
+ )
35
+
36
+ # Apply the remediation
37
+ context = SvgConform::ValidationContext.new(document, nil)
38
+ changes = remediation.apply(document, context)
39
+
40
+ # Verify changes were made
41
+ expect(changes).to be_an(Array)
42
+ puts "Applied #{changes.count} changes in #{fixture_name}" if changes.any?
43
+
44
+ # Get the remediated XML
45
+ actual_xml = document.to_xml
46
+ expected_xml = File.read(expected_output_file)
47
+
48
+ # Use canon matcher for XML equivalence
49
+ expect(actual_xml).to be_analogous_with(expected_xml)
50
+ end
51
+
52
+ it "produces valid XML after remediation" do
53
+ skip "Input file not found" unless File.exist?(input_file)
54
+
55
+ document = SvgConform::Document.from_file(input_file)
56
+ remediation = described_class.new(
57
+ id: "style_promotion_fix",
58
+ description: "Test style promotion remediation",
59
+ )
60
+
61
+ # Apply the remediation
62
+ context = SvgConform::ValidationContext.new(document, nil)
63
+ remediation.apply(document, context)
64
+
65
+ # Get the remediated XML
66
+ actual_xml = document.to_xml
67
+
68
+ # Basic XML validity check
69
+ expect(actual_xml).to include("<svg")
70
+ expect(actual_xml).to include("</svg>")
71
+ expect do
72
+ SvgConform::Document.from_content(actual_xml)
73
+ end.not_to raise_error
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "configuration" do
79
+ it "can be instantiated with basic parameters" do
80
+ remediation = described_class.new(
81
+ id: "test_style_promotion_fix",
82
+ description: "Test remediation",
83
+ )
84
+
85
+ expect(remediation).to be_a(described_class)
86
+ end
87
+
88
+ it "responds to apply method" do
89
+ remediation = described_class.new(
90
+ id: "test_style_promotion_fix",
91
+ description: "Test remediation",
92
+ )
93
+
94
+ expect(remediation).to respond_to(:apply)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Remediations::ViewboxRemediation do
7
+ let(:fixtures_dir) { "spec/fixtures/viewbox" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/viewbox/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/viewbox/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/viewbox/inputs/#{fixture_name}.svg" }
20
+ let(:expected_output_file) do
21
+ "spec/fixtures/viewbox/repair/#{fixture_name}.svg"
22
+ end
23
+
24
+ it "applies remediation and produces expected output" do
25
+ skip "Input file not found" unless File.exist?(input_file)
26
+ skip "Expected output file not found" unless File.exist?(expected_output_file)
27
+
28
+ document = SvgConform::Document.from_file(input_file)
29
+ remediation = described_class.new(
30
+ id: "viewbox_fix",
31
+ description: "Test viewbox remediation",
32
+ )
33
+
34
+ # Apply the remediation
35
+ context = SvgConform::ValidationContext.new(document, nil)
36
+ changes = remediation.apply(document, context)
37
+
38
+ # Verify changes were made
39
+ expect(changes).to be_an(Array)
40
+ puts "Applied #{changes.count} changes in #{fixture_name}" if changes.any?
41
+
42
+ # Get the remediated XML
43
+ actual_xml = document.to_xml
44
+ expected_xml = File.read(expected_output_file)
45
+
46
+ # Use canon matcher for XML equivalence
47
+ expect(actual_xml).to be_analogous_with(expected_xml)
48
+ end
49
+
50
+ it "produces valid XML after remediation" do
51
+ skip "Input file not found" unless File.exist?(input_file)
52
+
53
+ document = SvgConform::Document.from_file(input_file)
54
+ remediation = described_class.new(
55
+ id: "viewbox_fix",
56
+ description: "Test viewbox remediation",
57
+ )
58
+
59
+ # Apply the remediation
60
+ context = SvgConform::ValidationContext.new(document, nil)
61
+ remediation.apply(document, context)
62
+
63
+ # Get the remediated XML
64
+ actual_xml = document.to_xml
65
+
66
+ # Basic XML validity check
67
+ expect(actual_xml).to include("<svg")
68
+ expect(actual_xml).to include("</svg>")
69
+ expect do
70
+ SvgConform::Document.from_content(actual_xml)
71
+ end.not_to raise_error
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "configuration" do
77
+ it "can be instantiated with basic parameters" do
78
+ remediation = described_class.new(
79
+ id: "test_viewbox_fix",
80
+ description: "Test remediation",
81
+ )
82
+
83
+ expect(remediation).to be_a(described_class)
84
+ end
85
+
86
+ it "responds to apply method" do
87
+ remediation = described_class.new(
88
+ id: "test_viewbox_fix",
89
+ description: "Test remediation",
90
+ )
91
+
92
+ expect(remediation).to respond_to(:apply)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "canon"
5
+
6
+ RSpec.describe SvgConform::Requirements::AllowedElementsRequirement do
7
+ let(:fixtures_dir) { "spec/fixtures/allowed_elements" }
8
+
9
+ # Get all fixture files that have both input and expected repair versions
10
+ fixture_files = Dir.glob("spec/fixtures/allowed_elements/inputs/*.svg").select do |input_file|
11
+ basename = File.basename(input_file)
12
+ File.exist?("spec/fixtures/allowed_elements/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/allowed_elements/inputs/#{fixture_name}.svg"
21
+ end
22
+ let(:expected_output_file) do
23
+ "spec/fixtures/allowed_elements/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: "allowed_elements",
32
+ description: "Test allowed elements requirement",
33
+ disallowed_elements: %w[script audio video animate animateColor
34
+ clipPath marker],
35
+ )
36
+
37
+ context = SvgConform::ValidationContext.new(document, nil)
38
+ requirement.validate_document(document, context)
39
+
40
+ expect(context.errors).not_to be_empty
41
+ puts "Found #{context.errors.count} violations in #{fixture_name}"
42
+
43
+ context.errors.each do |error|
44
+ expect(error.requirement_id).to eq("allowed_elements")
45
+ expect(error.message).to be_a(String)
46
+ expect(error.message).not_to be_empty
47
+ end
48
+ end
49
+
50
+ it "correctly identifies specific violations" do
51
+ skip "Input file not found" unless File.exist?(input_file)
52
+
53
+ document = SvgConform::Document.from_file(input_file)
54
+ requirement = described_class.new(
55
+ id: "allowed_elements",
56
+ description: "Test allowed elements requirement",
57
+ disallowed_elements: %w[script audio video animate animateColor
58
+ clipPath marker],
59
+ )
60
+
61
+ context = SvgConform::ValidationContext.new(document, nil)
62
+ requirement.validate_document(document, context)
63
+
64
+ # Check that errors are specific to disallowed elements or attributes
65
+ context.errors.each do |error|
66
+ expect(error.message).to match(/Element .* is not allowed|Attribute .* is not allowed/)
67
+ end
68
+ end
69
+
70
+ it "passes validation for documents with only allowed elements" do
71
+ # Create a simple valid document for testing
72
+ allowed_svg = <<~SVG
73
+ <?xml version="1.0"?>
74
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
75
+ <g>
76
+ <rect x="10" y="10" width="20" height="20" fill="black"/>
77
+ <circle cx="50" cy="50" r="10" fill="black"/>
78
+ <text x="10" y="80">Test</text>
79
+ </g>
80
+ </svg>
81
+ SVG
82
+
83
+ document = SvgConform::Document.from_content(allowed_svg)
84
+ requirement = described_class.new(
85
+ id: "allowed_elements",
86
+ description: "Test allowed elements requirement",
87
+ disallowed_elements: %w[], # No disallowed elements, so it should pass
88
+ )
89
+
90
+ context = SvgConform::ValidationContext.new(document, nil)
91
+ requirement.validate_document(document, context)
92
+
93
+ expect(context.errors).to be_empty
94
+ end
95
+ end
96
+ end
97
+
98
+ describe "configuration" do
99
+ it "accepts custom allowed elements list" do
100
+ requirement = described_class.new(
101
+ id: "test_allowed_elements",
102
+ description: "Test with custom elements",
103
+ disallowed_elements: %w[script iframe embed],
104
+ )
105
+
106
+ expect(requirement.disallowed_elements).to eq(%w[script iframe embed])
107
+ end
108
+
109
+ it "can be instantiated with basic parameters" do
110
+ requirement = described_class.new(
111
+ id: "test_allowed_elements",
112
+ description: "Test requirement",
113
+ )
114
+
115
+ expect(requirement).to be_a(described_class)
116
+ end
117
+ end
118
+ end