# class Gem::FakeFetcher

A fake `Gem::RemoteFetcher` for use in tests or to avoid real live HTTP requests when testing code that uses RubyGems.

Example:

    @fetcher = Gem::FakeFetcher.new
    @fetcher.data['http://gems.example.com/yaml'] = source_index.to_yaml
    Gem::RemoteFetcher.fetcher = @fetcher

    use nested array if multiple response is needed

    @fetcher.data['http://gems.example.com/sequence'] = [['Success', 200, 'OK'], ['Failed', 401, 'Unauthorized']]

    @fetcher.fetch_path('http://gems.example.com/sequence') # => ['Success', 200, 'OK']
    @fetcher.fetch_path('http://gems.example.com/sequence') # => ['Failed', 401, 'Unauthorized']

    # invoke RubyGems code

    paths = @fetcher.paths
    assert_equal 'http://gems.example.com/yaml', paths.shift
    assert paths.empty?, paths.join(', ')

See RubyGems' tests for more examples of `FakeFetcher`.

### Attributes

data[R]
last_request[R]
paths[RW]

### Public Class Methods

new() click to toggle source

    # File lib/rubygems/test_utilities.rb, line 36
    def initialize
      @data = {}
      @paths = []
    end

### Public Instance Methods

cache_update_path(uri, path = nil, update = true) click to toggle source

    # File lib/rubygems/test_utilities.rb, line 77
    def cache_update_path(uri, path = nil, update = true)
      if data = fetch_path(uri)
        open(path, 'wb') {|io| io.write data } if path and update
        data
      else
        Gem.read_binary(path) if path
      end
    end

download(spec, source_uri, install_dir = Gem.dir) click to toggle source

    # File lib/rubygems/test_utilities.rb, line 135
    def download(spec, source_uri, install_dir = Gem.dir)
      name = File.basename spec.cache_file
      path = if Dir.pwd == install_dir # see fetch_command
               install_dir
             else
               File.join install_dir, "cache"
             end

      path = File.join path, name

      if source_uri =~ /^http/
        File.open(path, "wb") do |f|
          f.write fetch_path(File.join(source_uri, "gems", name))
        end
      else
        FileUtils.cp source_uri, path
      end

      path
    end

download_to_cache(dependency) click to toggle source

    # File lib/rubygems/test_utilities.rb, line 156
    def download_to_cache(dependency)
      found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency

      return if found.empty?

      spec, source = found.first

      download spec, source.uri.to_s
    end

fetch_path(path, mtime = nil, head = false) click to toggle source

    # File lib/rubygems/test_utilities.rb, line 64
    def fetch_path(path, mtime = nil, head = false)
      data = find_data(path)

      if data.respond_to?(:call)
        data.call
      else
        if path.to_s.end_with?(".gz") and not data.nil? and not data.empty?
          data = Gem::Util.gunzip data
        end
        data
      end
    end

fetch_size(path) click to toggle source

    # File lib/rubygems/test_utilities.rb, line 120
    def fetch_size(path)
      path = path.to_s
      @paths << path

      raise ArgumentError, 'need full URI' unless path =~ %r{^http://}

      unless @data.key? path
        raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
      end

      data = @data[path]

      data.respond_to?(:call) ? data.call : data.length
    end

find_data(path) click to toggle source

    # File lib/rubygems/test_utilities.rb, line 41
    def find_data(path)
      return Gem.read_binary path.path if URI === path and 'file' == path.scheme

      if URI === path and "URI::#{path.scheme.upcase}" != path.class.name
        raise ArgumentError,
          "mismatch for scheme #{path.scheme} and class #{path.class}"
      end

      path = path.to_s
      @paths << path
      raise ArgumentError, 'need full URI' unless path.start_with?("https://", "http://")

      unless @data.key? path
        raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
      end

      if @data[path].kind_of?(Array) && @data[path].first.kind_of?(Array)
        @data[path].shift
      else
        @data[path]
      end
    end

open_uri_or_path(path) click to toggle source

Thanks, FakeWeb!

    # File lib/rubygems/test_utilities.rb, line 87
    def open_uri_or_path(path)
      data = find_data(path)
      body, code, msg = data

      response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
      response.instance_variable_set(:@body, body)
      response.instance_variable_set(:@read, true)
      response
    end

request(uri, request_class, last_modified = nil) { |last_request| ... } click to toggle source

    # File lib/rubygems/test_utilities.rb, line 97
    def request(uri, request_class, last_modified = nil)
      data = find_data(uri)
      body, code, msg = (data.respond_to?(:call) ? data.call : data)

      @last_request = request_class.new uri.request_uri
      yield @last_request if block_given?

      response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
      response.instance_variable_set(:@body, body)
      response.instance_variable_set(:@read, true)
      response
    end