diff --git a/.github/workflows/lint-app.yml b/.github/workflows/lint-app.yml index b090c23..99b48ce 100644 --- a/.github/workflows/lint-app.yml +++ b/.github/workflows/lint-app.yml @@ -6,7 +6,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a54570..012cbb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes will be documented in this file. +## 1.4.0 - 2026-03-04 + +- (AlexT) When finding wrapper type, select the most specific type if more are available + ## 1.3.0 - 2025-01-16 - (AlexT) Add template endpoints https://github.com/epimorphics/sapi-client-ruby/pull/64 diff --git a/Gemfile.lock b/Gemfile.lock index ea0d08f..b4c138e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sapi-client-ruby (1.3.0) + sapi-client-ruby (1.4.0) faraday_middleware (~> 1.0.0) i18n (~> 1.5) diff --git a/lib/sapi_client/resource_wrapper.rb b/lib/sapi_client/resource_wrapper.rb index 8ed63c8..45363fa 100644 --- a/lib/sapi_client/resource_wrapper.rb +++ b/lib/sapi_client/resource_wrapper.rb @@ -30,14 +30,22 @@ def self.default_resource_wrapper_type # Find the first wrapper type for which there is an existing # class constant with the same name. If no such value is # found, return the default resource wrapper + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength def self.find_wrapper_type(types) - Array(types).each do |type| - wrapper = wrapper_class_constant(de_uri(type)) - return wrapper if wrapper + all_wrapped = Array(types) + .map { |type| wrapper_class_constant(de_uri(type)) } + .filter { |wrapper| !wrapper.nil? } + most_specific_wrapped = all_wrapped + .filter do |t| + all_wrapped.none? do |a| + t != a && a.respond_to?(:ancestors) && a.ancestors.include?(t) + end end + return most_specific_wrapped[0] unless most_specific_wrapped.empty? default_resource_wrapper_type end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength # Return the wrapper class for the given resource. If the # `options` specifies the wrapper class, then use that. diff --git a/lib/sapi_client/version.rb b/lib/sapi_client/version.rb index b70d69a..88ff5e8 100644 --- a/lib/sapi_client/version.rb +++ b/lib/sapi_client/version.rb @@ -2,7 +2,7 @@ module SapiClient MAJOR = 1 - MINOR = 3 + MINOR = 4 FIX = 0 VERSION = "#{MAJOR}.#{MINOR}.#{FIX}" end diff --git a/test/sapi_client/resource_wrapper_test.rb b/test/sapi_client/resource_wrapper_test.rb index 5977a20..db24118 100644 --- a/test/sapi_client/resource_wrapper_test.rb +++ b/test/sapi_client/resource_wrapper_test.rb @@ -3,10 +3,13 @@ require 'test_helper' require 'sapi_client' -class WombleResource +class CommonResource def initialize(_ignored); end end +class WombleResource < CommonResource +end + module SapiClient class ResourceWrapperTest < Minitest::Test describe 'ResourceWrapper' do @@ -42,6 +45,13 @@ class ResourceWrapperTest < Minitest::Test ).must_equal(WombleResource) end + it 'should find the most specific matching wrapper type' do + _( + ResourceWrapper + .find_wrapper_type(%i[CommonResource Wimbledon WombleResource Array]) + ).must_equal(WombleResource) + end + it 'should return nil if a wrapper cannot be found' do _( ResourceWrapper