Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 134 additions & 25 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2026-01-27 00:27:35 UTC using RuboCop version 1.82.1.
# on 2026-04-04 08:57:24 UTC using RuboCop version 1.86.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_argument, with_fixed_indentation
Layout/ArgumentAlignment:
Gemspec/RequireMFA:
Exclude:
- 'lib/svg_conform/requirements/invalid_id_references_requirement.rb'
- 'svg_conform.gemspec'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Expand All @@ -24,28 +22,42 @@ Layout/BlockAlignment:

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
# SupportedHashRocketStyles: key, separator, table
# SupportedColonStyles: key, separator, table
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/HashAlignment:
# Configuration parameters: EnforcedStyle.
# SupportedStyles: leading, trailing
Layout/LineContinuationLeadingSpace:
Exclude:
- 'spec/svg_conform/validation_context_spec.rb'
- 'spec/svgcheck_compatibility_spec.rb'

# Offense count: 5
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented
Layout/LineEndStringConcatenationIndentation:
Exclude:
- 'lib/svg_conform/external_checkers/svgcheck/validation_pipeline.rb'
- 'spec/svgcheck_compatibility_spec.rb'

# Offense count: 662
# Offense count: 649
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
# URISchemes: http, https
Layout/LineLength:
Enabled: false

# Offense count: 2
# Offense count: 13
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowInHeredoc.
Layout/TrailingWhitespace:
Lint/AmbiguousOperatorPrecedence:
Exclude:
- 'lib/svg_conform/requirements/invalid_id_references_requirement.rb'
- 'spec/svg_conform/validation_context_spec.rb'
- 'lib/svg_conform/compatibility_analyzer.rb'
- 'lib/svg_conform/semantic_comparator.rb'
- 'lib/svg_conform/validation_result.rb'

# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: RequireParenthesesForMethodChains.
Lint/AmbiguousRange:
Exclude:
- 'lib/svg_conform/compatibility/report_formatter.rb'

# Offense count: 3
# Configuration parameters: AllowedMethods.
Expand Down Expand Up @@ -73,10 +85,11 @@ Lint/DuplicateCaseCondition:
Exclude:
- 'lib/svg_conform/semantic_comparator.rb'

# Offense count: 1
# Offense count: 2
Lint/DuplicateMethods:
Exclude:
- 'lib/svg_conform/sax_validation_handler.rb'
- 'spec/svg_conform/validation_context_spec.rb'

# Offense count: 2
Lint/HashCompareByIdentity:
Expand All @@ -92,11 +105,18 @@ Lint/MissingSuper:
- 'lib/svg_conform/sax_validation_handler.rb'

# Offense count: 1
Lint/UnreachableCode:
# This cop supports unsafe autocorrection (--autocorrect-all).
Lint/RedundantDirGlobSort:
Exclude:
- 'lib/svg_conform/commands/check.rb'
- 'lib/tasks/fixtures.rake'

# Offense count: 146
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Lint/SuppressedExceptionInNumberConversion:
Exclude:
- 'lib/svg_conform/remediations/viewbox_remediation.rb'

# Offense count: 145
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
Metrics/AbcSize:
Enabled: false
Expand All @@ -117,7 +137,7 @@ Metrics/BlockNesting:
Metrics/CyclomaticComplexity:
Enabled: false

# Offense count: 259
# Offense count: 256
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
Max: 154
Expand All @@ -132,13 +152,31 @@ Metrics/ParameterLists:
Metrics/PerceivedComplexity:
Enabled: false

# Offense count: 9
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
# AllowedMethods: call
# WaywardPredicates: infinite?, nonzero?
Naming/PredicateMethod:
Exclude:
- 'lib/svg_conform/compatibility/file_processor.rb'
- 'lib/svg_conform/node_helpers.rb'
- 'lib/svg_conform/remediations/base_remediation.rb'
- 'lib/svg_conform/requirements/style_requirement.rb'
- 'lib/svg_conform/semantic_comparator.rb'

# Offense count: 2
# Configuration parameters: MinSize.
Performance/CollectionLiteralInLoop:
Exclude:
- 'lib/svg_conform/batch_report.rb'
- 'lib/svg_conform/compatibility/pattern_discovery.rb'

# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
Performance/MapCompact:
Exclude:
- 'lib/svg_conform/remediations/viewbox_remediation.rb'

# Offense count: 9
# Configuration parameters: IgnoredMetadata.
RSpec/DescribeClass:
Expand Down Expand Up @@ -168,6 +206,11 @@ RSpec/LeakyConstantDeclaration:
Exclude:
- 'spec/svg_conform/profiles/svg_1_2_rfc_profile_spec.rb'

# Offense count: 1
RSpec/LeakyLocalVariable:
Exclude:
- 'spec/svgcheck_compatibility_spec.rb'

# Offense count: 2
# Configuration parameters: .
# SupportedStyles: have_received, receive
Expand All @@ -183,11 +226,22 @@ RSpec/MultipleDescribes:
RSpec/MultipleExpectations:
Max: 8

# Offense count: 44
# This cop supports unsafe autocorrection (--autocorrect-all).
RSpec/Output:
Enabled: false

# Offense count: 1
Rake/MethodDefinitionInTask:
Exclude:
- 'lib/tasks/svgcheck.rake'

# Offense count: 3
# This cop supports safe autocorrection (--autocorrect).
Style/ComparableClamp:
Exclude:
- 'lib/svg_conform/css_color.rb'

# Offense count: 2
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, AllowComments.
Expand All @@ -205,9 +259,28 @@ Style/FormatStringToken:
EnforcedStyle: unannotated

# Offense count: 1
Style/MissingRespondToMissing:
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowSplatArgument.
Style/HashConversion:
Exclude:
- 'lib/svg_conform/sax_validation_handler.rb'

# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/HashSlice:
Exclude:
- 'lib/svg_conform/cli.rb'
- 'spec/svg_conform_spec.rb'

# Offense count: 1
# Configuration parameters: AllowedClasses.
Style/OneClassPerFile:
Exclude:
- 'lib/svg_conform/compatibility/report_formatter.rb'

# Offense count: 1
Style/OpenStructUse:
Exclude:
- 'lib/svg_conform/validator.rb'

# Offense count: 4
# Configuration parameters: AllowedMethods.
Expand All @@ -216,10 +289,46 @@ Style/OptionalBooleanParameter:
Exclude:
- 'lib/svg_conform/semantic_comparator.rb'

# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/PartitionInsteadOfDoubleSelect:
Exclude:
- 'lib/svg_conform/requirements/style_requirement.rb'

# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/ReduceToHash:
Exclude:
- 'lib/svg_conform/requirements/base_requirement.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowedMethods.
# AllowedMethods: nonzero?
# AllowedMethods: infinite?, nonzero?
Style/RedundantCondition:
Exclude:
- 'lib/svg_conform/external_checkers/svgcheck/parser.rb'

# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/RedundantFormat:
Exclude:
- 'lib/svg_conform/compatibility/report_formatter.rb'

# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/SelectByKind:
Exclude:
- 'lib/svg_conform/sax_validation_handler.rb'

# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/SelectByRegexp:
Exclude:
- 'lib/svg_conform/remediations/color_remediation.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Style/SuperArguments:
Exclude:
- 'lib/svg_conform/requirements/invalid_id_references_requirement.rb'
115 changes: 115 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build/Test Commands

```bash
# Install dependencies
bin/setup

# Run tests
rake spec

# Run a single spec file
bundle exec rspec spec/svg_conform/validator_spec.rb

# Run tests with detailed output
bundle exec rspec --format documentation

# Run linting
rake rubocop

# Run both tests and linting
rake

# Run a specific test by line number
bundle exec rspec spec/svg_conform/validator_spec.rb:42
```

## Architecture

### Two-Mode Validation System

SvgConform uses two distinct operating modes:

1. **SAX Validation Mode** (always used for validation):
- Memory-safe streaming XML parser
- Constant memory regardless of file size
- Handles files of any size (tested with 100MB+)
- Read-only, cannot modify documents
- Implemented via `SaxDocument` and `SaxValidationHandler`

2. **DOM Remediation Mode** (only when applying fixes):
- Full document tree loaded in memory
- XPath queries and tree modification
- Memory scales with file size
- Only activated when `fix: true` is specified

### Core Classes

- `Validator` - Main entry point; normalizes all inputs to SAX validation
- `SaxDocument` - SAX-based document wrapper for memory-safe validation
- `Document` - DOM-based document wrapper for modifications
- `Profile` - Collection of requirements and remediations; loaded from YAML
- `Profiles` - Factory for loading/retrieving profile instances
- `ValidationContext` - Carries state during validation (errors, data collected)
- `ValidationResult` - Holds validation outcomes after checking
- `ConformanceReport` - Formats validation results for output

### Requirements System

Requirements validate SVG documents. All requirements must support SAX validation:

- Requirements inherit from `BaseRequirement` in `lib/svg_conform/requirements/`
- Must implement `validate_sax_element(element, context)` for immediate checks
- Can optionally implement `collect_sax_data()` + `validate_sax_complete()` for deferred validation (e.g., cross-reference checks)
- Use `context.data` hash for per-document state (not instance variables - they leak across validations)
- Never attempt DOM operations in SAX callbacks

Key requirement classes: `NamespaceRequirement`, `ViewboxRequiredRequirement`, `IdReferenceRequirement`, `ForbiddenContentRequirement`, `ColorRestrictionsRequirement`, etc.

### Remediations System

Remediations fix validation failures. They run in DOM mode:

- Inherit from `BaseRemediation` in `lib/svg_conform/remediations/`
- Linked to requirements via `targets` array in profile YAML
- Only execute when `should_execute?(failed_requirements)` returns true

### Profile Configuration

Profiles are defined in YAML under `config/profiles/`:
- `base.yml` - Common requirements shared by other profiles
- `metanorma.yml`, `svg_1_2_rfc.yml`, etc. - Specific profile definitions
- Profile class map is built dynamically from filesystem in `Profile.build_class_map`

Profiles support `import` to inherit from other profiles (e.g., `metanorma` imports `base`).

### CLI Structure

- `lib/svg_conform/cli.rb` - Thor-based CLI entry point
- `lib/svg_conform/commands/check.rb` - Main validation command
- `lib/svg_conform/commands/profiles.rb` - Profile listing command
- `lib/svg_conform/commands/svgcheck.rb` - SVGCheck compatibility subcommands

### Input Handling

The `Validator` accepts multiple input types and always uses SAX:
- String (XML content) → parsed directly with SAX
- Moxml/Nokogiri documents → serialized once, then SAX validated
- Document/Element objects → same serialization approach

This ensures memory safety for large files regardless of input type.

### Key Files

- `lib/svg_conform.rb` - Main require file with autoloads
- `lib/svg_conform/element_proxy.rb` - Lightweight SAX element representation
- `lib/svg_conform/validation_context.rb` - Validation state container
- `lib/svg_conform/sax_document.rb` - SAX document wrapper
- `lib/svg_conform/sax_validation_handler.rb` - SAX callback handler

### Error Handling Pattern

The CLI uses `exit 1` for error exits. When improving error handling, prefer raising proper Ruby exceptions (`ValidationError`, `ProfileError`, `ArgumentError`) rather than using `exit`/`abort` directly, as Thor provides mechanisms for displaying errors gracefully to users.
Loading
Loading