Skip to content

Return openapi_version as a Gem::Version so SpecValidator rules can compare ranges - #209

Merged
geemus merged 3 commits into
ota42y:masterfrom
takayamaki:version-comparable
Sep 23, 2026
Merged

geemus merged 3 commits into
ota42y:masterfrom
takayamaki:version-comparable

Conversation

@takayamaki

Copy link
Copy Markdown
Contributor

Why

OpenAPI#openapi_version returns a Symbol (:v3_0 / :v3_1 / :unknown),
and every SpecValidator rule compares it with ==.
A 3.2 document therefore falls into :unknown, and no rule runs on it.
This blocks 3.2 support (see #152).

What

  • openapi_version now returns a Gem::Version, or nil when the openapi field is missing or is not a major.minor[.patch] string.
    A prerelease tag is dropped (3.1.0-rc1 => 3.1.0), matching the old prefix behavior.
  • SpecValidator::Rule gets version_before?(boundary) and version_at_least?(boundary).
    Both return false for an unknown version.
  • The *In30 rules use version_before?('3.1').
    NullableDeprecation, ExampleSingularDeprecation, ExclusiveMinimum and ExclusiveMaximum use version_at_least?('3.1'),
    so a 3.2 document is checked by them too.
  • A 4.0.0 document is no longer special-cased as unknown; it is simply a version greater than 3.1.
    The "unknown version" spec contexts now use a non-version string.

openapi_version is not released yet (added in #192), so this is not a breaking change.

Tests

  • spec/openapi_parser/schemas/open_api_spec.rb: the accessor cases, including 3.2.0, prerelease, 4.0.0, missing, non-string, and non-version strings
  • spec/openapi_parser/spec_validator/rule_spec.rb: the two range helpers
  • 3.2 contexts added to the four 3.1-or-later rule specs

bundle exec rake passes on Ruby 3.3 / 4.0 (rspec 497 examples, steep clean).
Ruby 2.7 checked by loading the library directly.

List the cases for returning openapi_version as a Gem::Version,
for the version range helpers on SpecValidator::Rule,
and for the 3.1-or-later rules applied to 3.2 documents.
Rules compare the declared version with == against a Symbol today,
which cannot express "3.1 or later".
version_before? and version_at_least? take a boundary string
and compare against a Gem::Version, returning false for an unknown version.
openapi_version returned :v3_0 / :v3_1 / :unknown and every rule
compared it with ==, so a 3.2 document fell into :unknown and no
rule ran on it.

It now returns Gem::Version (prerelease dropped) or nil when the
field is missing or not a major.minor[.patch] string.
Rules use version_before?('3.1') / version_at_least?('3.1'),
so the 3.1-or-later rules (nullable, singular example,
Boolean exclusiveMinimum / exclusiveMaximum) also cover 3.2.
@takayamaki
takayamaki marked this pull request as ready for review September 19, 2026 07:48

@geemus geemus left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants