Commit 1b8bb3c3 by Joost Baaij

Merge branch 'master' of git://github.com/thoughtbot/paperclip

parents 289d9cfb e23d7f51
......@@ -5,3 +5,6 @@ test/s3.yml
public
paperclip*.gem
capybara*.html
*.rbc
.bundle
*SPIKE*
appraise "rails2" do
gem "rails", "~>2.3.0"
end
appraise "rails3" do
gem "rails", "~>3.0.0"
end
source "http://rubygems.org"
gem "shoulda"
gem "mocha"
gem "rake"
gem "ruby-debug"
gem "aws-s3", :require => "aws/s3"
gem "sqlite3-ruby", "~>1.3.0"
gem "appraisal"
GEM
remote: http://rubygems.org/
specs:
appraisal (0.1)
bundler
rake
aws-s3 (0.6.2)
builder
mime-types
xml-simple
builder (3.0.0)
columnize (0.3.2)
linecache (0.43)
mime-types (1.16)
mocha (0.9.9)
rake
rake (0.8.7)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
shoulda (2.11.3)
sqlite3-ruby (1.3.2)
xml-simple (1.0.12)
PLATFORMS
ruby
DEPENDENCIES
appraisal
aws-s3
mocha
rake
ruby-debug
shoulda
sqlite3-ruby (~> 1.3.0)
......@@ -15,7 +15,13 @@ useful defaults.
See the documentation for +has_attached_file+ in Paperclip::ClassMethods for
more detailed options.
The complete RDoc[http://rdoc.info/projects/thoughtbot/paperclip] is online.
The complete RDoc[http://rdoc.info/gems/paperclip] is online.
==Installation
Include the gem in your Gemfile:
gem "paperclip", "~> 2.3"
==Installation
......
require 'rubygems'
require 'appraisal'
require 'bundler/setup'
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
......@@ -6,11 +10,11 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
require 'paperclip'
desc 'Default: run unit tests.'
task :default => [:clean, :test]
task :default => [:clean, :all]
desc 'Test the paperclip plugin under all supported Rails versions.'
task :all do |t|
exec('rake RAILS_VERSION=2.1 && rake RAILS_VERSION=2.3 && rake RAILS_VERSION=3.0')
exec('rake appraisal test')
end
desc 'Test the paperclip plugin.'
......
# This file was generated by Appraisal
source "http://rubygems.org"
gem "ruby-debug"
gem "rails", "~>2.3.0"
gem "rake"
gem "sqlite3-ruby", "~>1.3.0"
gem "shoulda"
gem "mocha"
gem "aws-s3", {:require=>"aws/s3"}
gem "appraisal"
\ No newline at end of file
GEM
remote: http://rubygems.org/
specs:
actionmailer (2.3.10)
actionpack (= 2.3.10)
actionpack (2.3.10)
activesupport (= 2.3.10)
rack (~> 1.1.0)
activerecord (2.3.10)
activesupport (= 2.3.10)
activeresource (2.3.10)
activesupport (= 2.3.10)
activesupport (2.3.10)
appraisal (0.1)
bundler
rake
aws-s3 (0.6.2)
builder
mime-types
xml-simple
builder (3.0.0)
columnize (0.3.2)
linecache (0.43)
mime-types (1.16)
mocha (0.9.9)
rake
rack (1.1.0)
rails (2.3.10)
actionmailer (= 2.3.10)
actionpack (= 2.3.10)
activerecord (= 2.3.10)
activeresource (= 2.3.10)
activesupport (= 2.3.10)
rake (>= 0.8.3)
rake (0.8.7)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
shoulda (2.11.3)
sqlite3-ruby (1.3.2)
xml-simple (1.0.12)
PLATFORMS
ruby
DEPENDENCIES
appraisal
aws-s3
mocha
rails (~> 2.3.0)
rake
ruby-debug
shoulda
sqlite3-ruby (~> 1.3.0)
# This file was generated by Appraisal
source "http://rubygems.org"
gem "ruby-debug"
gem "rails", ">=3.0.3"
gem "rake"
gem "sqlite3-ruby", "~>1.3.0"
gem "shoulda"
gem "mocha"
gem "aws-s3", {:require=>"aws/s3"}
gem "appraisal"
\ No newline at end of file
GEM
remote: http://rubygems.org/
specs:
abstract (1.0.0)
actionmailer (3.0.3)
actionpack (= 3.0.3)
mail (~> 2.2.9)
actionpack (3.0.3)
activemodel (= 3.0.3)
activesupport (= 3.0.3)
builder (~> 2.1.2)
erubis (~> 2.6.6)
i18n (~> 0.4)
rack (~> 1.2.1)
rack-mount (~> 0.6.13)
rack-test (~> 0.5.6)
tzinfo (~> 0.3.23)
activemodel (3.0.3)
activesupport (= 3.0.3)
builder (~> 2.1.2)
i18n (~> 0.4)
activerecord (3.0.3)
activemodel (= 3.0.3)
activesupport (= 3.0.3)
arel (~> 2.0.2)
tzinfo (~> 0.3.23)
activeresource (3.0.3)
activemodel (= 3.0.3)
activesupport (= 3.0.3)
activesupport (3.0.3)
appraisal (0.1)
bundler
rake
arel (2.0.4)
aws-s3 (0.6.2)
builder
mime-types
xml-simple
builder (2.1.2)
columnize (0.3.2)
erubis (2.6.6)
abstract (>= 1.0.0)
i18n (0.4.2)
linecache (0.43)
mail (2.2.10)
activesupport (>= 2.3.6)
i18n (~> 0.4.1)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
mocha (0.9.9)
rake
polyglot (0.3.1)
rack (1.2.1)
rack-mount (0.6.13)
rack (>= 1.0.0)
rack-test (0.5.6)
rack (>= 1.0)
rails (3.0.3)
actionmailer (= 3.0.3)
actionpack (= 3.0.3)
activerecord (= 3.0.3)
activeresource (= 3.0.3)
activesupport (= 3.0.3)
bundler (~> 1.0)
railties (= 3.0.3)
railties (3.0.3)
actionpack (= 3.0.3)
activesupport (= 3.0.3)
rake (>= 0.8.7)
thor (~> 0.14.4)
rake (0.8.7)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
shoulda (2.11.3)
sqlite3-ruby (1.3.2)
thor (0.14.6)
treetop (1.4.9)
polyglot (>= 0.3.1)
tzinfo (0.3.23)
xml-simple (1.0.12)
PLATFORMS
ruby
DEPENDENCIES
appraisal
aws-s3
mocha
rails (>= 3.0.3)
rake
ruby-debug
shoulda
sqlite3-ruby (~> 1.3.0)
......@@ -37,6 +37,7 @@ require 'paperclip/thumbnail'
require 'paperclip/interpolations'
require 'paperclip/style'
require 'paperclip/attachment'
require 'paperclip/storage'
require 'paperclip/callback_compatability'
require 'paperclip/command_line'
require 'paperclip/railtie'
......@@ -103,15 +104,6 @@ module Paperclip
CommandLine.new(cmd, *params).run
end
def included base #:nodoc:
base.extend ClassMethods
if base.respond_to?("set_callback")
base.send :include, Paperclip::CallbackCompatability::Rails3
else
base.send :include, Paperclip::CallbackCompatability::Rails21
end
end
def processor name #:nodoc:
name = name.to_s.camelize
processor = Paperclip.const_get(name)
......@@ -121,6 +113,12 @@ module Paperclip
processor
end
def each_instance_with_attachment(klass, name)
Object.const_get(klass).all.each do |instance|
yield(instance) if instance.send(:"#{name}?")
end
end
# Log a paperclip-specific line. Uses ActiveRecord::Base.logger
# by default. Set Paperclip.options[:log] to false to turn off.
def log message
......@@ -159,6 +157,17 @@ module Paperclip
class InfiniteInterpolationError < PaperclipError #:nodoc:
end
module Glue
def self.included base #:nodoc:
base.extend ClassMethods
if base.respond_to?("set_callback")
base.send :include, Paperclip::CallbackCompatability::Rails3
else
base.send :include, Paperclip::CallbackCompatability::Rails21
end
end
end
module ClassMethods
# +has_attached_file+ gives the class it is called on an attribute that maps to a file. This
# is typically a file stored somewhere on the filesystem and has been uploaded by a user.
......
......@@ -4,6 +4,7 @@ module Paperclip
# when the model saves, deletes when the model is destroyed, and processes
# the file upon assignment.
class Attachment
include IOStream
def self.default_options
@default_options ||= {
......@@ -88,11 +89,11 @@ module Paperclip
return nil if uploaded_file.nil?
@queued_for_write[:original] = uploaded_file.to_tempfile
@queued_for_write[:original] = to_tempfile(uploaded_file)
instance_write(:file_name, uploaded_file.original_filename.strip)
instance_write(:content_type, uploaded_file.content_type.to_s.strip)
instance_write(:file_size, uploaded_file.size.to_i)
instance_write(:fingerprint, uploaded_file.fingerprint)
instance_write(:fingerprint, generate_fingerprint(uploaded_file))
instance_write(:updated_at, Time.now)
@dirty = true
......@@ -101,7 +102,7 @@ module Paperclip
# Reset the file size if the original file was reprocessed.
instance_write(:file_size, @queued_for_write[:original].size.to_i)
instance_write(:fingerprint, @queued_for_write[:original].fingerprint)
instance_write(:fingerprint, generate_fingerprint(@queued_for_write[:original]))
ensure
uploaded_file.close if close_uploaded_file
end
......@@ -180,7 +181,7 @@ module Paperclip
# Returns the hash of the file as originally assigned, and lives in the
# <attachment>_fingerprint attribute of the model.
def fingerprint
instance_read(:fingerprint) || (@queued_for_write[:original] && @queued_for_write[:original].fingerprint)
instance_read(:fingerprint) || (@queued_for_write[:original] && generate_fingerprint(@queued_for_write[:original]))
end
# Returns the content_type of the file as originally assigned, and lives
......@@ -196,6 +197,12 @@ module Paperclip
time && time.to_f.to_i
end
def generate_fingerprint(source)
data = source.read
source.rewind if source.respond_to?(:rewind)
Digest::MD5.hexdigest(data)
end
# Paths and URLs can have a number of variables interpolated into them
# to vary the storage location based on name, id, style, class, etc.
# This method is a deprecated access into supplying and retrieving these
......@@ -277,13 +284,12 @@ module Paperclip
end
def initialize_storage #:nodoc:
storage_name = @storage.to_s.capitalize
storage_class_name = @storage.to_s.capitalize
begin
require "paperclip/storage/#{@storage}"
rescue MissingSourceFile
raise StorageMethodNotFound, "Cannot find the '#{@storage}' storage adapter."
@storage_module = Paperclip::Storage.const_get(storage_class_name)
rescue NameError
raise StorageMethodNotFound, "Cannot load storage module '#{storage_class_name}'"
end
@storage_module = Paperclip::Storage.const_get(storage_name)
self.extend(@storage_module)
end
......
......@@ -8,7 +8,7 @@ module Paperclip
@binary = binary.dup
@params = params.dup
@options = options.dup
@swallow_stderr = @options.delete(:swallow_stderr)
@swallow_stderr = @options.has_key?(:swallow_stderr) ? @options.delete(:swallow_stderr) : Paperclip.options[:swallow_stderr]
@expected_outcodes = @options.delete(:expected_outcodes)
@expected_outcodes ||= [0]
end
......
......@@ -41,8 +41,9 @@ module Paperclip
# Returns the interpolated URL. Will raise an error if the url itself
# contains ":url" to prevent infinite recursion. This interpolation
# is used in the default :path to ease default specifications.
RIGHT_HERE = "#{__FILE__.gsub(%r{^\./}, "")}:#{__LINE__ + 3}"
def url attachment, style_name
raise InfiniteInterpolationError if caller.any?{|b| b.index("#{__FILE__}:#{__LINE__ + 1}") }
raise InfiniteInterpolationError if caller.any?{|b| b.index(RIGHT_HERE) }
attachment.url(style_name, false)
end
......
# Provides method that can be included on File-type objects (IO, StringIO, Tempfile, etc) to allow stream copying
# and Tempfile conversion.
module IOStream
# Returns a Tempfile containing the contents of the readable object.
def to_tempfile
name = respond_to?(:original_filename) ? original_filename : (respond_to?(:path) ? path : "stream")
tempfile = Paperclip::Tempfile.new("stream" + File.extname(name))
def to_tempfile(object)
return object.to_tempfile if object.respond_to?(:to_tempfile)
name = object.respond_to?(:original_filename) ? object.original_filename : (object.respond_to?(:path) ? object.path : "stream")
tempfile = Paperclip::Tempfile.new(["stream", File.extname(name)])
tempfile.binmode
self.stream_to(tempfile)
stream_to(object, tempfile)
end
# Copies one read-able object from one place to another in blocks, obviating the need to load
# the whole thing into memory. Defaults to 8k blocks. If this module is included in both
# StringIO and Tempfile, then either can have its data copied anywhere else without typing
# worries or memory overhead worries. Returns a File if a String is passed in as the destination
# and returns the IO or Tempfile as passed in if one is sent as the destination.
def stream_to path_or_file, in_blocks_of = 8192
# the whole thing into memory. Defaults to 8k blocks. Returns a File if a String is passed
# in as the destination and returns the IO or Tempfile as passed in if one is sent as the destination.
def stream_to object, path_or_file, in_blocks_of = 8192
dstio = case path_or_file
when String then File.new(path_or_file, "wb+")
when IO then path_or_file
when Tempfile then path_or_file
end
buffer = ""
self.rewind
while self.read(in_blocks_of, buffer) do
object.rewind
while object.read(in_blocks_of, buffer) do
dstio.write(buffer)
end
dstio.rewind
......@@ -31,18 +29,6 @@ module IOStream
end
end
class IO #:nodoc:
include IOStream
end
%w( Tempfile StringIO ).each do |klass|
if Object.const_defined? klass
Object.const_get(klass).class_eval do
include IOStream
end
end
end
# Corrects a bug in Windows when asking for Tempfile size.
if defined? Tempfile
class Tempfile
......
......@@ -40,10 +40,19 @@ module Paperclip
# on this blog post:
# http://marsorange.com/archives/of-mogrify-ruby-tempfile-dynamic-class-definitions
class Tempfile < ::Tempfile
# Replaces Tempfile's +make_tmpname+ with one that honors file extensions.
# This is Ruby 1.8.7's implementation.
if RUBY_VERSION <= "1.8.6"
def make_tmpname(basename, n)
extension = File.extname(basename)
sprintf("%s,%d,%d%s", File.basename(basename, extension), $$, n.to_i, extension)
case basename
when Array
prefix, suffix = *basename
else
prefix, suffix = basename, ''
end
t = Time.now.strftime("%y%m%d")
path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}-#{n}#{suffix}"
end
end
end
end
......@@ -17,7 +17,7 @@ module Paperclip
class Railtie
def self.insert
ActiveRecord::Base.send(:include, Paperclip)
ActiveRecord::Base.send(:include, Paperclip::Glue)
File.send(:include, Paperclip::Upfile)
end
end
......
require "paperclip/storage/filesystem"
require "paperclip/storage/s3"
......@@ -56,6 +56,7 @@ module Paperclip
while(true)
path = File.dirname(path)
FileUtils.rmdir(path)
break if File.exists?(path) # Ruby 1.9.2 does not raise if the removal failed.
end
rescue Errno::EEXIST, Errno::ENOTEMPTY, Errno::ENOENT, Errno::EINVAL, Errno::ENOTDIR
# Stop trying to remove parent directories
......
......@@ -127,12 +127,20 @@ module Paperclip
# style, in the format most representative of the current storage.
def to_file style = default_style
return @queued_for_write[style] if @queued_for_write[style]
file = Tempfile.new(path(style))
filename = path(style)
extname = File.extname(filename)
basename = File.basename(filename, extname)
file = Tempfile.new([basename, extname])
file.binmode
file.write(AWS::S3::S3Object.value(path(style), bucket_name))
file.rewind
return file
end
def create_bucket
AWS::S3::Bucket.create(bucket_name)
end
def flush_writes #:nodoc:
@queued_for_write.each do |style, file|
begin
......@@ -143,6 +151,9 @@ module Paperclip
{:content_type => instance_read(:content_type),
:access => @s3_permissions,
}.merge(@s3_headers))
rescue AWS::S3::NoSuchBucket => e
create_bucket
retry
rescue AWS::S3::ResponseError => e
raise
end
......
......@@ -45,7 +45,7 @@ module Paperclip
# that contains the new image.
def make
src = @file
dst = Tempfile.new([@basename, @format].compact.join("."))
dst = Tempfile.new([@basename, @format ? ".#{@format}" : ''])
dst.binmode
begin
......
......@@ -32,11 +32,6 @@ module Paperclip
def size
File.size(self)
end
# Returns the hash of the file.
def fingerprint
Digest::MD5.hexdigest(self.read)
end
end
end
......
module Paperclip
VERSION = "2.3.3" unless defined? Paperclip::VERSION
VERSION = "2.3.8" unless defined? Paperclip::VERSION
end
def obtain_class
class_name = ENV['CLASS'] || ENV['class']
raise "Must specify CLASS" unless class_name
@klass = Object.const_get(class_name)
class_name
end
def obtain_attachments
def obtain_attachments(klass)
klass = Object.const_get(klass.to_s)
name = ENV['ATTACHMENT'] || ENV['attachment']
raise "Class #{@klass.name} has no attachments specified" unless @klass.respond_to?(:attachment_definitions)
if !name.blank? && @klass.attachment_definitions.keys.include?(name)
raise "Class #{klass.name} has no attachments specified" unless klass.respond_to?(:attachment_definitions)
if !name.blank? && klass.attachment_definitions.keys.include?(name)
[ name ]
else
@klass.attachment_definitions.keys
klass.attachment_definitions.keys
end
end
def for_all_attachments
klass = obtain_class
names = obtain_attachments
ids = klass.connection.select_values(klass.send(:construct_finder_sql, :select => 'id'))
ids.each do |id|
instance = klass.find(id)
names.each do |name|
result = if instance.send("#{ name }?")
yield(instance, name)
else
true
end
print result ? "." : "x"; $stdout.flush
end
end
puts " Done."
end
namespace :paperclip do
desc "Refreshes both metadata and thumbnails."
task :refresh => ["paperclip:refresh:metadata", "paperclip:refresh:thumbnails"]
......@@ -41,17 +23,23 @@ namespace :paperclip do
desc "Regenerates thumbnails for a given CLASS (and optional ATTACHMENT)."
task :thumbnails => :environment do
errors = []
for_all_attachments do |instance, name|
klass = obtain_class
names = obtain_attachments(klass)
names.each do |name|
Paperclip.each_instance_with_attachment(klass, name) do |instance|
result = instance.send(name).reprocess!
errors << [instance.id, instance.errors] unless instance.errors.blank?
result
end
end
errors.each{|e| puts "#{e.first}: #{e.last.full_messages.inspect}" }
end
desc "Regenerates content_type/size metadata for a given CLASS (and optional ATTACHMENT)."
task :metadata => :environment do
for_all_attachments do |instance, name|
klass = obtain_class
names = obtain_attachments(klass)
names.each do |name|
Paperclip.each_instance_with_attachment(klass, name) do |instance|
if file = instance.send(name).to_file
instance.send("#{name}_file_name=", instance.send("#{name}_file_name").strip)
instance.send("#{name}_content_type=", file.content_type.strip)
......@@ -63,10 +51,14 @@ namespace :paperclip do
end
end
end
end
desc "Cleans out invalid attachments. Useful after you've added new validations."
task :clean => :environment do
for_all_attachments do |instance, name|
klass = obtain_class
names = obtain_attachments(klass)
names.each do |name|
Paperclip.each_instance_with_attachment(klass, name) do |instance|
instance.send(name).send(:validate)
if instance.send(name).valid?
true
......@@ -76,4 +68,5 @@ namespace :paperclip do
end
end
end
end
end
......@@ -28,6 +28,7 @@ spec = Gem::Specification.new do |s|
s.add_dependency 'activerecord'
s.add_dependency 'activesupport'
s.add_development_dependency 'shoulda'
s.add_development_dependency 'appraisal'
s.add_development_dependency 'mocha'
s.add_development_dependency 'aws-s3'
s.add_development_dependency 'sqlite3-ruby'
......
# encoding: utf-8
require 'test/helper'
require './test/helper'
class Dummy
# This is a dummy class
......@@ -463,14 +463,11 @@ class AttachmentTest < Test::Unit::TestCase
setup do
rebuild_model
@not_file = mock
@tempfile = mock
@not_file = mock("not_file")
@tempfile = mock("tempfile")
@not_file.stubs(:nil?).returns(false)
@not_file.stubs(:fingerprint).returns('bd94545193321376b70136f8b223abf8')
@tempfile.stubs(:fingerprint).returns('bd94545193321376b70136f8b223abf8')
@not_file.expects(:size).returns(10)
@tempfile.expects(:size).returns(10)
@not_file.expects(:to_tempfile).returns(@tempfile)
@not_file.expects(:original_filename).returns("sheep_say_bæ.png\r\n")
@not_file.expects(:content_type).returns("image/png\r\n")
......@@ -479,6 +476,9 @@ class AttachmentTest < Test::Unit::TestCase
@attachment.expects(:valid_assignment?).with(@not_file).returns(true)
@attachment.expects(:queue_existing_for_delete)
@attachment.expects(:post_process)
@attachment.expects(:to_tempfile).returns(@tempfile)
@attachment.expects(:generate_fingerprint).with(@tempfile).returns("12345")
@attachment.expects(:generate_fingerprint).with(@not_file).returns("12345")
@dummy.avatar = @not_file
end
......@@ -606,7 +606,7 @@ class AttachmentTest < Test::Unit::TestCase
[:large, :medium, :small].each do |style|
io = @attachment.to_file(style)
# p "in commit to disk test, io is #{io.inspect} and @instance.id is #{@instance.id}"
assert File.exists?(io)
assert File.exists?(io.path)
assert ! io.is_a?(::Tempfile)
io.close
end
......@@ -703,7 +703,7 @@ class AttachmentTest < Test::Unit::TestCase
now = Time.now
Time.stubs(:now).returns(now)
@dummy.avatar = @file
assert now, @dummy.avatar.updated_at
assert_equal now.to_i, @dummy.avatar.updated_at.to_i
end
should "return nil when reloaded and sent #avatar_updated_at" do
......
require 'test/helper'
require './test/helper'
class CommandLineTest < Test::Unit::TestCase
def setup
......@@ -7,13 +7,13 @@ class CommandLineTest < Test::Unit::TestCase
end
should "take a command and parameters and produce a shell command for bash" do
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png")
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
assert_equal "convert a.jpg b.png", cmd.command
end
should "be able to set a path and produce commands with that path" do
Paperclip::CommandLine.path = "/opt/bin"
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png")
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
assert_equal "/opt/bin/convert a.jpg b.png", cmd.command
end
......@@ -21,7 +21,8 @@ class CommandLineTest < Test::Unit::TestCase
cmd = Paperclip::CommandLine.new("convert",
":one :{two}",
:one => "a.jpg",
:two => "b.png")
:two => "b.png",
:swallow_stderr => false)
assert_equal "convert 'a.jpg' 'b.png'", cmd.command
end
......@@ -30,7 +31,8 @@ class CommandLineTest < Test::Unit::TestCase
cmd = Paperclip::CommandLine.new("convert",
":one :{two}",
:one => "a.jpg",
:two => "b.png")
:two => "b.png",
:swallow_stderr => false)
assert_equal 'convert "a.jpg" "b.png"', cmd.command
end
......@@ -38,7 +40,8 @@ class CommandLineTest < Test::Unit::TestCase
cmd = Paperclip::CommandLine.new("convert",
":one :two",
:one => "`rm -rf`.jpg",
:two => "ha'ha.png")
:two => "ha'ha.png",
:swallow_stderr => false)
assert_equal "convert '`rm -rf`.jpg' 'ha'\\''ha.png'", cmd.command
end
......@@ -47,7 +50,8 @@ class CommandLineTest < Test::Unit::TestCase
cmd = Paperclip::CommandLine.new("convert",
":one :two",
:one => "`rm -rf`.jpg",
:two => "ha'ha.png")
:two => "ha'ha.png",
:swallow_stderr => false)
assert_equal %{convert "`rm -rf`.jpg" "ha'ha.png"}, cmd.command
end
......@@ -80,7 +84,7 @@ class CommandLineTest < Test::Unit::TestCase
end
should "run the #command it's given and return the output" do
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png")
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
with_exitstatus_returning(0) do
assert_equal :correct_value, cmd.run
......@@ -88,7 +92,7 @@ class CommandLineTest < Test::Unit::TestCase
end
should "raise a PaperclipCommandLineError if the result code isn't expected" do
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png")
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
with_exitstatus_returning(1) do
assert_raises(Paperclip::PaperclipCommandLineError) do
......@@ -100,7 +104,8 @@ class CommandLineTest < Test::Unit::TestCase
should "not raise a PaperclipCommandLineError if the result code is expected" do
cmd = Paperclip::CommandLine.new("convert",
"a.jpg b.png",
:expected_outcodes => [0, 1])
:expected_outcodes => [0, 1],
:swallow_stderr => false)
cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
with_exitstatus_returning(1) do
assert_nothing_raised do
......@@ -110,7 +115,7 @@ class CommandLineTest < Test::Unit::TestCase
end
should "log the command" do
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png")
cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
cmd.class.stubs(:'`')
Paperclip.expects(:log).with("convert a.jpg b.png")
cmd.run
......
require 'test/helper'
require './test/helper'
class GeometryTest < Test::Unit::TestCase
context "Paperclip::Geometry" do
......
......@@ -5,18 +5,6 @@ require 'test/unit'
require 'shoulda'
require 'mocha'
case ENV['RAILS_VERSION']
when '2.1' then
gem 'activerecord', '~>2.1.0'
gem 'activesupport', '~>2.1.0'
when '3.0' then
gem 'activerecord', '~>3.0.0'
gem 'activesupport', '~>3.0.0'
else
gem 'activerecord', '~>2.3.0'
gem 'activesupport', '~>2.3.0'
end
require 'active_record'
require 'active_record/version'
require 'active_support'
......@@ -53,7 +41,7 @@ $LOAD_PATH << File.join(ROOT, 'lib', 'paperclip')
require File.join(ROOT, 'lib', 'paperclip.rb')
require 'shoulda_macros/paperclip'
require './shoulda_macros/paperclip'
FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
......@@ -61,10 +49,10 @@ ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FIL
ActiveRecord::Base.establish_connection(config['test'])
def reset_class class_name
ActiveRecord::Base.send(:include, Paperclip)
ActiveRecord::Base.send(:include, Paperclip::Glue)
Object.send(:remove_const, class_name) rescue nil
klass = Object.const_set(class_name, Class.new(ActiveRecord::Base))
klass.class_eval{ include Paperclip }
klass.class_eval{ include Paperclip::Glue }
klass
end
......@@ -90,11 +78,11 @@ def rebuild_model options = {}
end
def rebuild_class options = {}
ActiveRecord::Base.send(:include, Paperclip)
ActiveRecord::Base.send(:include, Paperclip::Glue)
Object.send(:remove_const, "Dummy") rescue nil
Object.const_set("Dummy", Class.new(ActiveRecord::Base))
Dummy.class_eval do
include Paperclip
include Paperclip::Glue
has_attached_file :avatar, options
end
end
......
require 'test/helper'
require './test/helper'
class IntegrationTest < Test::Unit::TestCase
context "Many models at once" do
......
require 'test/helper'
require './test/helper'
class InterpolationsTest < Test::Unit::TestCase
should "return all methods but the infrastructure when sent #all" do
......
require 'test/helper'
require './test/helper'
class IOStreamTest < Test::Unit::TestCase
context "IOStream" do
should "be included in IO, File, Tempfile, and StringIO" do
[IO, File, Tempfile, StringIO].each do |klass|
assert klass.included_modules.include?(IOStream), "Not in #{klass}"
end
end
end
include IOStream
context "A file" do
setup do
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
......@@ -21,7 +14,7 @@ class IOStreamTest < Test::Unit::TestCase
context "and given a String" do
setup do
FileUtils.mkdir_p(File.join(ROOT, 'tmp'))
assert @result = @file.stream_to(File.join(ROOT, 'tmp', 'iostream.string.test'))
assert @result = stream_to(@file, File.join(ROOT, 'tmp', 'iostream.string.test'))
end
should "return a File" do
......@@ -38,7 +31,7 @@ class IOStreamTest < Test::Unit::TestCase
setup do
tempfile = Tempfile.new('iostream.test')
tempfile.binmode
assert @result = @file.stream_to(tempfile)
assert @result = stream_to(@file, tempfile)
end
should "return a Tempfile" do
......@@ -53,9 +46,9 @@ class IOStreamTest < Test::Unit::TestCase
end
context "that is sent #to_tempfile" do
context "that is converted #to_tempfile" do
setup do
assert @tempfile = @file.to_tempfile
assert @tempfile = to_tempfile(@file)
end
should "convert it to a Paperclip Tempfile" do
......
require 'test/helper'
require './test/helper'
class HaveAttachedFileMatcherTest < Test::Unit::TestCase
context "have_attached_file" do
......
require 'test/helper'
require './test/helper'
class ValidateAttachmentContentTypeMatcherTest < Test::Unit::TestCase
context "validate_attachment_content_type" do
......
require 'test/helper'
require './test/helper'
class ValidateAttachmentPresenceMatcherTest < Test::Unit::TestCase
context "validate_attachment_presence" do
......
require 'test/helper'
require './test/helper'
class ValidateAttachmentSizeMatcherTest < Test::Unit::TestCase
context "validate_attachment_size" do
......
require 'test/helper'
require './test/helper'
class PaperclipTest < Test::Unit::TestCase
context "Calling Paperclip.run" do
......@@ -43,6 +43,23 @@ class PaperclipTest < Test::Unit::TestCase
end
end
context "Paperclip.each_instance_with_attachment" do
setup do
@file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
d1 = Dummy.create(:avatar => @file)
d2 = Dummy.create
d3 = Dummy.create(:avatar => @file)
@expected = [d1, d3]
end
should "yield every instance of a model that has an attachment" do
actual = []
Paperclip.each_instance_with_attachment("Dummy", "avatar") do |instance|
actual << instance
end
assert_same_elements @expected, actual
end
end
should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
end
......@@ -172,6 +189,12 @@ class PaperclipTest < Test::Unit::TestCase
end
end
should "not have Attachment in the ActiveRecord::Base namespace" do
assert_raises(NameError) do
ActiveRecord::Base::Attachment
end
end
def self.should_validate validation, options, valid_file, invalid_file
context "with #{validation} validation and #{options.inspect} options" do
setup do
......
require 'test/helper'
require './test/helper'
class ProcessorTest < Test::Unit::TestCase
should "instantiate and call #make when sent #make to the class" do
......
require 'test/helper'
require './test/helper'
require 'aws/s3'
class StorageTest < Test::Unit::TestCase
......@@ -185,6 +185,21 @@ class StorageTest < Test::Unit::TestCase
end
end
context "and saved without a bucket" do
setup do
class AWS::S3::NoSuchBucket < AWS::S3::ResponseError
# Force the class to be created as a proper subclass of ResponseError thanks to AWS::S3's autocreation of exceptions
end
AWS::S3::Bucket.expects(:create).with("testing")
AWS::S3::S3Object.stubs(:store).raises(AWS::S3::NoSuchBucket.new(:message, :response)).then.returns(true)
@dummy.save
end
should "succeed" do
assert true
end
end
context "and remove" do
setup do
AWS::S3::S3Object.stubs(:exists?).returns(true)
......@@ -336,6 +351,11 @@ class StorageTest < Test::Unit::TestCase
should "be on S3" do
assert true
end
should "generate a tempfile with the right name" do
file = @dummy.avatar.to_file
assert_match /^original.*\.png$/, File.basename(file.path)
end
end
end
end
......
# encoding: utf-8
require 'test/helper'
require './test/helper'
class StyleTest < Test::Unit::TestCase
......
require 'test/helper'
require './test/helper'
class ThumbnailTest < Test::Unit::TestCase
context "A Paperclip Tempfile" do
setup do
@tempfile = Paperclip::Tempfile.new("file.jpg")
@tempfile = Paperclip::Tempfile.new(["file", ".jpg"])
end
should "have its path contain a real extension" do
......
require 'test/helper'
require './test/helper'
class UpfileTest < Test::Unit::TestCase
{ %w(jpg jpe jpeg) => 'image/jpeg',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment