class Rack::Test::UploadedFile

Wraps a Tempfile with a content type. Including one or more UploadedFile’s in the params causes Rack::Test to build and issue a multipart request.

Example:

post "/photos", "file" => Rack::Test::UploadedFile.new("me.jpg", "image/jpeg")

Attributes

content_type[RW]

The content type of the “uploaded” file

original_filename[R]

The filename, not including the path, of the “uploaded” file

tempfile[R]

The tempfile

Public Class Methods

actually_finalize(file) click to toggle source

Close and unlink the given file, used as a finalizer for the tempfile, if the tempfile is backed by a file in the filesystem.

# File lib/rack/test/uploaded_file.rb, line 82
def self.actually_finalize(file)
  file.close
  file.unlink
end
finalize(file) click to toggle source

A proc that can be used as a finalizer to close and unlink the tempfile.

# File lib/rack/test/uploaded_file.rb, line 76
def self.finalize(file)
  proc { actually_finalize file }
end
new(content, content_type = 'text/plain', binary = false, original_filename: nil) click to toggle source

Creates a new UploadedFile instance.

Arguments:

content

is a path to a file, or an {IO} or {StringIO} object representing the content.

content_type

MIME type of the file

binary

Whether the file should be set to binmode (content treated as binary).

original_filename

The filename to use for the file. Required if content is StringIO, optional override if not

# File lib/rack/test/uploaded_file.rb, line 31
def initialize(content, content_type = 'text/plain', binary = false, original_filename: nil)
  @content_type = content_type
  @original_filename = original_filename

  case content
  when StringIO
    initialize_from_stringio(content)
  else
    initialize_from_file_path(content)
  end

  @tempfile.binmode if binary
end

Public Instance Methods

append_to(buffer) click to toggle source

Append to given buffer in 64K chunks to avoid multiple large copies of file data in memory. Rewind tempfile before and after to make sure all data in tempfile is appended to the buffer.

# File lib/rack/test/uploaded_file.rb, line 60
def append_to(buffer)
  tempfile.rewind

  buf = String.new
  buffer << tempfile.readpartial(65_536, buf) until tempfile.eof?

  tempfile.rewind

  nil
end
local_path()
Alias for: path
method_missing(method_name, *args, &block) click to toggle source

Delegate all methods not handled to the tempfile.

# File lib/rack/test/uploaded_file.rb, line 52
def method_missing(method_name, *args, &block)
  tempfile.public_send(method_name, *args, &block)
end
path() click to toggle source

The path to the tempfile. Will not work if the receiver’s content is from a StringIO.

# File lib/rack/test/uploaded_file.rb, line 46
def path
  tempfile.path
end
Also aliased as: local_path

Private Instance Methods

initialize_from_file_path(path) click to toggle source

Create a tempfile and copy the content from the given path into the tempfile, optionally renaming if original_filename has been set.

# File lib/rack/test/uploaded_file.rb, line 98
def initialize_from_file_path(path)
  raise "#{path} file does not exist" unless ::File.exist?(path)

  @original_filename ||= ::File.basename(path)
  extension = ::File.extname(@original_filename)

  @tempfile = Tempfile.new([::File.basename(@original_filename, extension), extension])
  @tempfile.set_encoding(Encoding::BINARY)

  ObjectSpace.define_finalizer(self, self.class.finalize(@tempfile))

  FileUtils.copy_file(path, @tempfile.path)
end
initialize_from_stringio(stringio) click to toggle source

Use the StringIO as the tempfile.

# File lib/rack/test/uploaded_file.rb, line 90
def initialize_from_stringio(stringio)
  raise(ArgumentError, 'Missing `original_filename` for StringIO object') unless @original_filename

  @tempfile = stringio
end