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
53 changes: 39 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
name: Ruby

on: [push,pull_request]
on: [push, pull_request]

jobs:
build:
test:
runs-on: ubuntu-latest
name: "rspec — Ruby ${{ matrix.ruby }} / ${{ matrix.gemfile }}"
strategy:
fail-fast: false
matrix:
# Covers the supported range from the floor (Ruby 3.2 / Rails 6.1) to
# the current ceiling (Ruby 3.4 / Rails 8.1). Curated pairs avoid
# Ruby/Rails combinations that are not mutually supported.
include:
- { ruby: "3.2", gemfile: rails_6_1 }
- { ruby: "3.2", gemfile: rails_7_1 }
- { ruby: "3.3", gemfile: rails_7_2 }
- { ruby: "3.3", gemfile: rails_8_0 }
- { ruby: "3.4", gemfile: rails_8_0 }
- { ruby: "3.4", gemfile: rails_8_1 }
env:
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2.2
bundler: 4.0.4
- name: Bundle gems
run: bundle install
- name: Run rspec
run: bundle exec rspec
- name: Run rubocop
run: bundle exec rubocop
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Run rspec
run: bundle exec rspec

lint:
runs-on: ubuntu-latest
name: rubocop
steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: true
- name: Run rubocop
run: bundle exec rubocop
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@

# built gem files
*.gem

# per-appraisal lockfiles (resolved fresh in CI)
gemfiles/*.gemfile.lock
29 changes: 10 additions & 19 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# Append to (rather than replace) RuboCop's default AllCops/Exclude, so the
# defaults such as vendor/**/* stay excluded. Without this, CI installs gems
# into vendor/bundle (bundler-cache) and RuboCop would lint third-party gems.
inherit_mode:
merge:
- Exclude

AllCops:
TargetRubyVersion: 3.2
NewCops: enable
SuggestExtensions: false
Exclude:
- "README.md"
- "vendor/**/*"
- "gemfiles/vendor/**/*"

Style/StringLiterals:
Enabled: true
Expand All @@ -20,24 +29,6 @@ Metrics/BlockLength:
Exclude:
- "spec/**/*_spec.rb"

Metrics/MethodLength:
Exclude:
- "lib/rspec/json_api/compare_hash.rb"
- "lib/extensions/hash.rb"

Metrics/AbcSize:
Exclude:
- "lib/rspec/json_api/compare_hash.rb"
- "lib/rspec/json_api/matchers/match_json_schema.rb"

Metrics/CyclomaticComplexity:
Exclude:
- "lib/rspec/json_api/compare_hash.rb"

Metrics/PerceivedComplexity:
Exclude:
- "lib/rspec/json_api/compare_hash.rb"

Style/Documentation:
Enabled: false

Expand All @@ -47,4 +38,4 @@ Naming/PredicatePrefix:

Naming/PredicateMethod:
Exclude:
- "lib/rspec/json_api/compare_hash.rb"
- "lib/rspec/json_api/schema_match.rb"
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
## [Unreleased]

## [1.5.0] - 2026-06-05

### Added
- CI compatibility matrix across Ruby 3.2–3.4 and Rails 6.1, 7.1, 7.2, 8.0 and 8.1 (`gemfiles/` + GitHub Actions matrix), so the advertised version support is actually tested.
- `RSpec::JsonApi::Constraints` module encapsulating the schema `Proc` options DSL.
- `RSpec::JsonApi::SchemaMatch` as the single comparison entry point, and `RSpec::JsonApi::Traversal` for the internal structural helpers.

### Changed
- Depend on `railties` instead of the full `rails` meta-gem; the gem only uses ActiveSupport core extensions and `Rails::Generators`. Drops the dependency graph from 87 to 65 gems. The `>= 6.1.4.1` floor is unchanged.
- Unified array and hash comparison behind `SchemaMatch`; removed the duplicate `CompareArray` and `CompareHash` modules.
- Stopped monkey-patching core `Hash`/`Array`; `deep_keys`, `deep_key_paths`, `deep_sort` and `sanitize!` moved into the internal `Traversal` module.
- The failure diff is now built lazily, only when a match fails.
- An unsupported schema `Proc` option now raises `ArgumentError` instead of being silently ignored.
- Generators emit `# frozen_string_literal: true` and freeze the generated interface hash.

### Fixed
- Require `uri` so the built-in types load on Ruby 4.0 (previously raised `NameError` on load).
- Anchor the `UUID` type with `\A...\z` so multiline strings no longer pass validation.
- Rescue invalid JSON in `match_json_schema` instead of raising `JSON::ParserError`.
- Avoid a `TypeError` when a schema expects a nested object but the actual value is a scalar.
- Enforce key structure for interface-array elements; an element with an extra null-valued key no longer matches.
- Reset the memoized diff at the start of `matches?` so a reused matcher reflects the current actual value.
- Use `Regexp#match?` for regex comparison so it returns a Boolean instead of a match index.

### Removed
- Dead/broken `interface.erb` generator template.

## [1.4.0] - 2026-01-23

### Changed
Expand Down
92 changes: 6 additions & 86 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,37 +1,15 @@
PATH
remote: .
specs:
rspec-json_api (1.4.0)
rspec-json_api (1.5.0)
activesupport (>= 6.1.4.1)
diffy (>= 3.4.2)
rails (>= 6.1.4.1)
railties (>= 6.1.4.1)
rspec-rails (>= 5.0.2)

GEM
remote: https://rubygems.org/
specs:
action_text-trix (2.1.16)
railties
actioncable (8.1.2)
actionpack (= 8.1.2)
activesupport (= 8.1.2)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (8.1.2)
actionpack (= 8.1.2)
activejob (= 8.1.2)
activerecord (= 8.1.2)
activestorage (= 8.1.2)
activesupport (= 8.1.2)
mail (>= 2.8.0)
actionmailer (8.1.2)
actionpack (= 8.1.2)
actionview (= 8.1.2)
activejob (= 8.1.2)
activesupport (= 8.1.2)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (8.1.2)
actionview (= 8.1.2)
activesupport (= 8.1.2)
Expand All @@ -42,35 +20,12 @@ GEM
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (8.1.2)
action_text-trix (~> 2.1.15)
actionpack (= 8.1.2)
activerecord (= 8.1.2)
activestorage (= 8.1.2)
activesupport (= 8.1.2)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (8.1.2)
activesupport (= 8.1.2)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (8.1.2)
activesupport (= 8.1.2)
globalid (>= 0.3.6)
activemodel (8.1.2)
activesupport (= 8.1.2)
activerecord (8.1.2)
activemodel (= 8.1.2)
activesupport (= 8.1.2)
timeout (>= 0.4.0)
activestorage (8.1.2)
actionpack (= 8.1.2)
activejob (= 8.1.2)
activerecord (= 8.1.2)
activesupport (= 8.1.2)
marcel (~> 1.0)
activesupport (8.1.2)
base64
bigdecimal
Expand All @@ -97,8 +52,6 @@ GEM
drb (2.2.3)
erb (6.0.1)
erubi (1.13.1)
globalid (1.3.0)
activesupport (>= 6.1)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
io-console (0.8.2)
Expand All @@ -113,30 +66,14 @@ GEM
loofah (2.25.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.9.0)
logger
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.1.0)
mini_mime (1.1.5)
minitest (6.0.1)
prism (~> 1.5)
net-imap (0.6.2)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.2)
timeout
net-smtp (0.5.1)
net-protocol
nio4r (2.7.5)
nokogiri (1.19.0-arm64-darwin)
racc (~> 1.4)
nokogiri (1.19.0-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.19.0-x86_64-linux-gnu)
racc (~> 1.4)
parallel (1.27.0)
parser (3.3.10.1)
ast (~> 2.4.1)
Expand All @@ -157,20 +94,6 @@ GEM
rack (>= 1.3)
rackup (2.3.1)
rack (>= 3)
rails (8.1.2)
actioncable (= 8.1.2)
actionmailbox (= 8.1.2)
actionmailer (= 8.1.2)
actionpack (= 8.1.2)
actiontext (= 8.1.2)
actionview (= 8.1.2)
activejob (= 8.1.2)
activemodel (= 8.1.2)
activerecord (= 8.1.2)
activestorage (= 8.1.2)
activesupport (= 8.1.2)
bundler (>= 1.15.0)
railties (= 8.1.2)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
Expand Down Expand Up @@ -231,7 +154,6 @@ GEM
securerandom (0.4.1)
stringio (3.2.0)
thor (1.5.0)
timeout (0.6.0)
tsort (0.2.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
Expand All @@ -240,15 +162,13 @@ GEM
unicode-emoji (4.2.0)
uri (1.1.1)
useragent (0.16.11)
websocket-driver (0.8.0)
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.7.4)

PLATFORMS
arm64-darwin-22
arm64-darwin-25
x86_64-darwin-20
x86_64-linux

DEPENDENCIES
activesupport (>= 6.1.4.1)
Expand Down
7 changes: 7 additions & 0 deletions gemfiles/rails_6_1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Inherits the dev dependencies from the root Gemfile and pins the Rails line
# under test. Generated/maintained for the CI compatibility matrix.
eval_gemfile File.expand_path("../Gemfile", __dir__)

gem "rails", "~> 6.1.0"
7 changes: 7 additions & 0 deletions gemfiles/rails_7_1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Inherits the dev dependencies from the root Gemfile and pins the Rails line
# under test. Generated/maintained for the CI compatibility matrix.
eval_gemfile File.expand_path("../Gemfile", __dir__)

gem "rails", "~> 7.1.0"
7 changes: 7 additions & 0 deletions gemfiles/rails_7_2.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Inherits the dev dependencies from the root Gemfile and pins the Rails line
# under test. Generated/maintained for the CI compatibility matrix.
eval_gemfile File.expand_path("../Gemfile", __dir__)

gem "rails", "~> 7.2.0"
7 changes: 7 additions & 0 deletions gemfiles/rails_8_0.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Inherits the dev dependencies from the root Gemfile and pins the Rails line
# under test. Generated/maintained for the CI compatibility matrix.
eval_gemfile File.expand_path("../Gemfile", __dir__)

gem "rails", "~> 8.0.0"
7 changes: 7 additions & 0 deletions gemfiles/rails_8_1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

# Inherits the dev dependencies from the root Gemfile and pins the Rails line
# under test. Generated/maintained for the CI compatibility matrix.
eval_gemfile File.expand_path("../Gemfile", __dir__)

gem "rails", "~> 8.1.0"
8 changes: 0 additions & 8 deletions lib/extensions/array.rb

This file was deleted.

Loading
Loading