Skip to content

Update Utils.deep_merge! to support OptionsLike #1650

@iMacTia

Description

@iMacTia

Update Utils.deep_merge! to Support OptionsLike

Phase: 1 - Foundation
Release Target: v2.x.0
Tracking Issue: #1647
RFC: docs/options-detach-plan.md

Overview

Update Faraday::Utils.deep_merge! to recognize OptionsLike objects instead of hardcoding checks for Faraday::Options. This enables both legacy Options and new BaseOptions subclasses to work with deep merging.

Current Code

File: lib/faraday/utils.rb (line 103)

if value.is_a?(Hash) && (target[key].is_a?(Hash) || target[key].is_a?(Options))

Proposed Change

if value.is_a?(Hash) && (target_value.is_a?(Hash) || target_value.is_a?(Faraday::OptionsLike))

Why: This allows deep_merge! to work uniformly with:

  • Legacy Faraday::Options (which will include OptionsLike)
  • New BaseOptions subclasses (which include OptionsLike)
  • Any future Options-like classes

Implementation Tasks

  • Review current Utils.deep_merge! implementation
  • Update the conditional check to use OptionsLike instead of Options
  • Update Faraday::Options to include OptionsLike module (for backward compatibility)
  • Add tests in spec/faraday/utils_spec.rb covering:
    • Deep merge with legacy Options objects
    • Deep merge with BaseOptions objects (using test subclass)
    • Deep merge with nested Options-like objects
    • Ensure existing behavior unchanged
  • Run full test suite
  • Integration tests pass (Add comprehensive integration tests using faraday-live approach #1648)

Files to Modify

  • lib/faraday/utils.rb (line ~103)
  • lib/faraday/options.rb (add include OptionsLike)
  • spec/faraday/utils_spec.rb (add/update tests)

Acceptance Criteria

  • deep_merge! works with both Options and BaseOptions subclasses
  • All existing tests pass
  • New tests cover OptionsLike behavior
  • No breaking changes to existing code

Dependencies

Backward Compatibility

This is backward compatible because:

  1. Legacy Options will include OptionsLike, so is_a?(OptionsLike) checks will pass
  2. The change broadens support rather than restricting it
  3. All existing deep_merge! behavior preserved

Testing Strategy

Create a test BaseOptions subclass in the spec to validate:

class TestOptions < Faraday::BaseOptions
  MEMBERS = [:foo, :bar].freeze
  COERCIONS = {}.freeze
  
  attr_accessor :foo, :bar
end

# Test that deep_merge! works with this class

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions