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/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/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