Back to Repositories

Testing Callback Isolation Mechanisms in CarrierWave Uploader

This test suite focuses on verifying callback isolation in CarrierWave’s uploader functionality, ensuring that callback registration and inheritance work correctly between different uploader classes. The tests validate that custom callbacks don’t leak between separate uploader implementations.

Test Coverage Overview

The test coverage focuses on callback isolation between different CarrierWave uploader classes. It verifies:

  • Default callback preservation in base uploader
  • Custom callback addition in derived uploader
  • Proper isolation between separate uploader classes
  • Verification of callback inheritance patterns

Implementation Analysis

The testing approach uses RSpec’s class-based setup to create isolated uploader instances and verify callback registration. It leverages let blocks for setup and implements multiple assertion patterns to validate callback behavior.

The implementation specifically tests callback registration using before(:cache) hooks and verifies array-based callback storage.

Technical Details

Testing tools and configuration include:

  • RSpec as the testing framework
  • CarrierWave’s Base uploader class
  • Dynamic class creation for isolation testing
  • Default callback configuration validation
  • Custom callback registration verification

Best Practices Demonstrated

The test suite demonstrates several testing best practices:

  • Isolated test scenarios using separate class instances
  • Clear setup and expectation separation
  • Comprehensive default behavior validation
  • Explicit state verification
  • Clean test organization using RSpec contexts

carrierwaveuploader/carrierwave

spec/uploader/callback_spec.rb

            
require 'spec_helper'

describe CarrierWave::Uploader do
  describe "callback isolation" do
    let(:default_before_callbacks) do
      [
        :check_extension_allowlist!,
        :check_extension_denylist!,
        :check_content_type_allowlist!,
        :check_content_type_denylist!,
        :check_size!,
        :check_dimensions!,
        :process!
      ]
    end

    let(:uploader_class_1) { Class.new(CarrierWave::Uploader::Base) }
    let(:uploader_class_2) { Class.new(CarrierWave::Uploader::Base) }

    before { uploader_class_2.before(:cache, :before_cache_callback) }

    it { expect(uploader_class_1._before_callbacks[:cache]).to eq(default_before_callbacks) }

    it { expect(uploader_class_2._before_callbacks[:cache]).to eq(default_before_callbacks + [:before_cache_callback]) }

    it "doesn't inherit the uploader 2 callback" do
      expect(uploader_class_1._before_callbacks[:cache]).to eq(default_before_callbacks)
    end
  end
end