paperclip-cloudfiles 2.3.1.1.0 → 2.3.1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -16,7 +16,11 @@ See the documentation for +has_attached_file+ in Paperclip::ClassMethods for
16
16
  more detailed options.
17
17
 
18
18
  This fork has support for Rackspace Cloud Files. It requires the "cloudfiles"
19
- gem, >= 1.4.4, from Gemcutter.org.
19
+ gem, >= 1.4.4, from Gemcutter.org. The Thoughtbot guys have indicated that they
20
+ don't want to pull any code into the official Paperclip mainline that they don't
21
+ personally use on projects, so until they discover the joy of Cloud Files, this
22
+ fork is available as the {paperclip-cloudfiles gem}[http://gemcutter.org/gems/paperclip-cloudfiles]
23
+ on Gemcutter's gem server.
20
24
 
21
25
  ==Quick Start
22
26
 
@@ -7,18 +7,19 @@ module Paperclip
7
7
 
8
8
  def self.default_options
9
9
  @default_options ||= {
10
- :url => "/system/:attachment/:id/:style/:filename",
11
- :path => ":rails_root/public:url",
12
- :styles => {},
13
- :default_url => "/:attachment/:style/missing.png",
14
- :default_style => :original,
15
- :validations => [],
16
- :storage => :filesystem,
17
- :whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
10
+ :url => "/system/:attachment/:id/:style/:filename",
11
+ :path => ":rails_root/public:url",
12
+ :styles => {},
13
+ :processors => [:thumbnail],
14
+ :convert_options => {},
15
+ :default_url => "/:attachment/:style/missing.png",
16
+ :default_style => :original,
17
+ :storage => :filesystem,
18
+ :whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
18
19
  }
19
20
  end
20
21
 
21
- attr_reader :name, :instance, :styles, :default_style, :convert_options, :queued_for_write, :options
22
+ attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny, :options
22
23
 
23
24
  # Creates an Attachment object. +name+ is the name of the attachment,
24
25
  # +instance+ is the ActiveRecord object instance it's attached to, and
@@ -34,33 +35,42 @@ module Paperclip
34
35
  @path = options[:path]
35
36
  @path = @path.call(self) if @path.is_a?(Proc)
36
37
  @styles = options[:styles]
37
- @styles = @styles.call(self) if @styles.is_a?(Proc)
38
+ @normalized_styles = nil
38
39
  @default_url = options[:default_url]
39
- @validations = options[:validations]
40
40
  @default_style = options[:default_style]
41
41
  @storage = options[:storage]
42
42
  @whiny = options[:whiny_thumbnails] || options[:whiny]
43
- @convert_options = options[:convert_options] || {}
44
- @processors = options[:processors] || [:thumbnail]
43
+ @convert_options = options[:convert_options]
44
+ @processors = options[:processors]
45
45
  @options = options
46
46
  @queued_for_delete = []
47
47
  @queued_for_write = {}
48
48
  @errors = {}
49
- @validation_errors = nil
50
49
  @dirty = false
51
50
 
52
- normalize_style_definition
53
51
  initialize_storage
54
52
  end
53
+
54
+ def styles
55
+ unless @normalized_styles
56
+ @normalized_styles = {}
57
+ (@styles.respond_to?(:call) ? @styles.call(self) : @styles).each do |name, args|
58
+ @normalized_styles[name] = Paperclip::Style.new(name, args, self)
59
+ end
60
+ end
61
+ @normalized_styles
62
+ end
63
+
64
+ def processors
65
+ @processors.respond_to?(:call) ? @processors.call(instance) : @processors
66
+ end
55
67
 
56
68
  # What gets called when you call instance.attachment = File. It clears
57
- # errors, assigns attributes, processes the file, and runs validations. It
69
+ # errors, assigns attributes, and processes the file. It
58
70
  # also queues up the previous file for deletion, to be flushed away on
59
71
  # #save of its host. In addition to form uploads, you can also assign
60
72
  # another Paperclip attachment:
61
73
  # new_user.avatar = old_user.avatar
62
- # If the file that is assigned is not valid, the processing (i.e.
63
- # thumbnailing, etc) will NOT be run.
64
74
  def assign uploaded_file
65
75
  ensure_required_accessors!
66
76
 
@@ -84,13 +94,12 @@ module Paperclip
84
94
 
85
95
  @dirty = true
86
96
 
87
- post_process if valid?
97
+ post_process
88
98
 
89
99
  # Reset the file size if the original file was reprocessed.
90
100
  instance_write(:file_size, @queued_for_write[:original].size.to_i)
91
101
  ensure
92
102
  uploaded_file.close if close_uploaded_file
93
- validate
94
103
  end
95
104
 
96
105
  # Returns the public URL of the attachment, with a given style. Note that
@@ -100,8 +109,8 @@ module Paperclip
100
109
  # security, however, for performance reasons. set
101
110
  # include_updated_timestamp to false if you want to stop the attachment
102
111
  # update time appended to the url
103
- def url style = default_style, include_updated_timestamp = true
104
- url = original_filename.nil? ? interpolate(@default_url, style) : interpolate(@url, style)
112
+ def url style_name = default_style, include_updated_timestamp = true
113
+ url = original_filename.nil? ? interpolate(@default_url, style_name) : interpolate(@url, style_name)
105
114
  include_updated_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url
106
115
  end
107
116
 
@@ -109,19 +118,13 @@ module Paperclip
109
118
  # file is stored in the filesystem the path refers to the path of the file
110
119
  # on disk. If the file is stored in S3, the path is the "key" part of the
111
120
  # URL, and the :bucket option refers to the S3 bucket.
112
- def path style = default_style
113
- original_filename.nil? ? nil : interpolate(@path, style)
121
+ def path style_name = default_style
122
+ original_filename.nil? ? nil : interpolate(@path, style_name)
114
123
  end
115
124
 
116
125
  # Alias to +url+
117
- def to_s style = nil
118
- url(style)
119
- end
120
-
121
- # Returns true if there are no errors on this attachment.
122
- def valid?
123
- validate
124
- errors.empty?
126
+ def to_s style_name = nil
127
+ url(style_name)
125
128
  end
126
129
 
127
130
  # Returns an array containing the errors on this attachment.
@@ -137,15 +140,10 @@ module Paperclip
137
140
  # Saves the file, if there are no errors. If there are, it flushes them to
138
141
  # the instance's errors and returns false, cancelling the save.
139
142
  def save
140
- if valid?
141
- flush_deletes
142
- flush_writes
143
- @dirty = false
144
- true
145
- else
146
- flush_errors
147
- false
148
- end
143
+ flush_deletes
144
+ flush_writes
145
+ @dirty = false
146
+ true
149
147
  end
150
148
 
151
149
  # Clears out the attachment. Has the same effect as previously assigning
@@ -154,7 +152,6 @@ module Paperclip
154
152
  def clear
155
153
  queue_existing_for_delete
156
154
  @errors = {}
157
- @validation_errors = nil
158
155
  end
159
156
 
160
157
  # Destroys the attachment. Has the same effect as previously assigning
@@ -267,82 +264,6 @@ module Paperclip
267
264
  file.nil? || (file.respond_to?(:original_filename) && file.respond_to?(:content_type))
268
265
  end
269
266
 
270
- def validate #:nodoc:
271
- unless @validation_errors
272
- @validation_errors = @validations.inject({}) do |errors, validation|
273
- name, options = validation
274
- errors[name] = send(:"validate_#{name}", options) if allow_validation?(options)
275
- errors
276
- end
277
- @validation_errors.reject!{|k,v| v == nil }
278
- @errors.merge!(@validation_errors)
279
- end
280
- @validation_errors
281
- end
282
-
283
- def allow_validation? options #:nodoc:
284
- (options[:if].nil? || check_guard(options[:if])) && (options[:unless].nil? || !check_guard(options[:unless]))
285
- end
286
-
287
- def check_guard guard #:nodoc:
288
- if guard.respond_to? :call
289
- guard.call(instance)
290
- elsif ! guard.blank?
291
- instance.send(guard.to_s)
292
- end
293
- end
294
-
295
- def validate_size options #:nodoc:
296
- if file? && !options[:range].include?(size.to_i)
297
- options[:message].gsub(/:min/, options[:min].to_s).gsub(/:max/, options[:max].to_s)
298
- end
299
- end
300
-
301
- def validate_presence options #:nodoc:
302
- options[:message] unless file?
303
- end
304
-
305
- def validate_content_type options #:nodoc:
306
- valid_types = [options[:content_type]].flatten
307
- unless original_filename.blank?
308
- unless valid_types.blank?
309
- content_type = instance_read(:content_type)
310
- unless valid_types.any?{|t| content_type.nil? || t === content_type }
311
- options[:message] || "is not one of the allowed file types."
312
- end
313
- end
314
- end
315
- end
316
-
317
- def normalize_style_definition #:nodoc:
318
- @styles.each do |name, args|
319
- unless args.is_a? Hash
320
- dimensions, format = [args, nil].flatten[0..1]
321
- format = nil if format.blank?
322
- @styles[name] = {
323
- :processors => @processors,
324
- :geometry => dimensions,
325
- :format => format,
326
- :whiny => @whiny,
327
- :convert_options => extra_options_for(name)
328
- }
329
- else
330
- @styles[name] = {
331
- :processors => @processors,
332
- :whiny => @whiny,
333
- :convert_options => extra_options_for(name)
334
- }.merge(@styles[name])
335
- end
336
- end
337
- end
338
-
339
- def solidify_style_definitions #:nodoc:
340
- @styles.each do |name, args|
341
- @styles[name][:geometry] = @styles[name][:geometry].call(instance) if @styles[name][:geometry].respond_to?(:call)
342
- @styles[name][:processors] = @styles[name][:processors].call(instance) if @styles[name][:processors].respond_to?(:call)
343
- end
344
- end
345
-
346
267
  def initialize_storage #:nodoc:
347
268
  @storage_module = Paperclip::Storage.const_get(@storage.to_s.classify)
348
269
  self.extend(@storage_module)
@@ -359,7 +280,6 @@ module Paperclip
359
280
 
360
281
  def post_process #:nodoc:
361
282
  return if @queued_for_write[:original].nil?
362
- solidify_style_definitions
363
283
  return if fire_events(:before)
364
284
  post_process_styles
365
285
  return if fire_events(:after)
@@ -375,11 +295,11 @@ module Paperclip
375
295
  end
376
296
 
377
297
  def post_process_styles #:nodoc:
378
- @styles.each do |name, args|
298
+ styles.each do |name, style|
379
299
  begin
380
- raise RuntimeError.new("Style #{name} has no processors defined.") if args[:processors].blank?
381
- @queued_for_write[name] = args[:processors].inject(@queued_for_write[:original]) do |file, processor|
382
- Paperclip.processor(processor).make(file, args, self)
300
+ raise RuntimeError.new("Style #{name} has no processors defined.") if style.processors.blank?
301
+ @queued_for_write[name] = style.processors.inject(@queued_for_write[:original]) do |file, processor|
302
+ Paperclip.processor(processor).make(file, style.processor_options, self)
383
303
  end
384
304
  rescue PaperclipError => e
385
305
  log("An error was received while processing: #{e.inspect}")
@@ -388,13 +308,13 @@ module Paperclip
388
308
  end
389
309
  end
390
310
 
391
- def interpolate pattern, style = default_style #:nodoc:
392
- Paperclip::Interpolations.interpolate(pattern, self, style)
311
+ def interpolate pattern, style_name = default_style #:nodoc:
312
+ Paperclip::Interpolations.interpolate(pattern, self, style_name)
393
313
  end
394
314
 
395
315
  def queue_existing_for_delete #:nodoc:
396
316
  return unless file?
397
- @queued_for_delete += [:original, *@styles.keys].uniq.map do |style|
317
+ @queued_for_delete += [:original, *styles.keys].uniq.map do |style|
398
318
  path(style) if exists?(style)
399
319
  end.compact
400
320
  instance_write(:file_name, nil)
@@ -34,30 +34,30 @@ module Paperclip
34
34
  end
35
35
 
36
36
  # Returns the filename, the same way as ":basename.:extension" would.
37
- def filename attachment, style
38
- "#{basename(attachment, style)}.#{extension(attachment, style)}"
37
+ def filename attachment, style_name
38
+ "#{basename(attachment, style_name)}.#{extension(attachment, style_name)}"
39
39
  end
40
40
 
41
41
  # Returns the interpolated URL. Will raise an error if the url itself
42
42
  # contains ":url" to prevent infinite recursion. This interpolation
43
43
  # is used in the default :path to ease default specifications.
44
- def url attachment, style
44
+ def url attachment, style_name
45
45
  raise InfiniteInterpolationError if attachment.options[:url].include?(":url")
46
- attachment.url(style, false)
46
+ attachment.url(style_name, false)
47
47
  end
48
48
 
49
49
  # Returns the timestamp as defined by the <attachment>_updated_at field
50
- def timestamp attachment, style
50
+ def timestamp attachment, style_name
51
51
  attachment.instance_read(:updated_at).to_s
52
52
  end
53
53
 
54
54
  # Returns the RAILS_ROOT constant.
55
- def rails_root attachment, style
55
+ def rails_root attachment, style_name
56
56
  RAILS_ROOT
57
57
  end
58
58
 
59
59
  # Returns the RAILS_ENV constant.
60
- def rails_env attachment, style
60
+ def rails_env attachment, style_name
61
61
  RAILS_ENV
62
62
  end
63
63
 
@@ -65,44 +65,44 @@ module Paperclip
65
65
  # e.g. "users" for the User class.
66
66
  # NOTE: The arguments need to be optional, because some tools fetch
67
67
  # all class names. Calling #class will return the expected class.
68
- def class attachment = nil, style = nil
69
- return super() if attachment.nil? && style.nil?
68
+ def class attachment = nil, style_name = nil
69
+ return super() if attachment.nil? && style_name.nil?
70
70
  attachment.instance.class.to_s.underscore.pluralize
71
71
  end
72
72
 
73
73
  # Returns the basename of the file. e.g. "file" for "file.jpg"
74
- def basename attachment, style
74
+ def basename attachment, style_name
75
75
  attachment.original_filename.gsub(/#{File.extname(attachment.original_filename)}$/, "")
76
76
  end
77
77
 
78
78
  # Returns the extension of the file. e.g. "jpg" for "file.jpg"
79
79
  # If the style has a format defined, it will return the format instead
80
80
  # of the actual extension.
81
- def extension attachment, style
82
- ((style = attachment.styles[style]) && style[:format]) ||
81
+ def extension attachment, style_name
82
+ ((style = attachment.styles[style_name]) && style[:format]) ||
83
83
  File.extname(attachment.original_filename).gsub(/^\.+/, "")
84
84
  end
85
85
 
86
86
  # Returns the id of the instance.
87
- def id attachment, style
87
+ def id attachment, style_name
88
88
  attachment.instance.id
89
89
  end
90
90
 
91
91
  # Returns the id of the instance in a split path form. e.g. returns
92
92
  # 000/001/234 for an id of 1234.
93
- def id_partition attachment, style
93
+ def id_partition attachment, style_name
94
94
  ("%09d" % attachment.instance.id).scan(/\d{3}/).join("/")
95
95
  end
96
96
 
97
97
  # Returns the pluralized form of the attachment name. e.g.
98
98
  # "avatars" for an attachment of :avatar
99
- def attachment attachment, style
99
+ def attachment attachment, style_name
100
100
  attachment.name.to_s.downcase.pluralize
101
101
  end
102
102
 
103
103
  # Returns the style, or the default style if nil is supplied.
104
- def style attachment, style
105
- style || attachment.default_style
104
+ def style attachment, style_name
105
+ style_name || attachment.default_style
106
106
  end
107
107
  end
108
108
  end
@@ -20,9 +20,9 @@ module Paperclip
20
20
  def self.extended base
21
21
  end
22
22
 
23
- def exists?(style = default_style)
23
+ def exists?(style_name = default_style)
24
24
  if original_filename
25
- File.exist?(path(style))
25
+ File.exist?(path(style_name))
26
26
  else
27
27
  false
28
28
  end
@@ -30,17 +30,17 @@ module Paperclip
30
30
 
31
31
  # Returns representation of the data of the file assigned to the given
32
32
  # style, in the format most representative of the current storage.
33
- def to_file style = default_style
34
- @queued_for_write[style] || (File.new(path(style), 'rb') if exists?(style))
33
+ def to_file style_name = default_style
34
+ @queued_for_write[style_name] || (File.new(path(style_name), 'rb') if exists?(style_name))
35
35
  end
36
36
 
37
37
  def flush_writes #:nodoc:
38
- @queued_for_write.each do |style, file|
38
+ @queued_for_write.each do |style_name, file|
39
39
  file.close
40
- FileUtils.mkdir_p(File.dirname(path(style)))
41
- log("saving #{path(style)}")
42
- FileUtils.mv(file.path, path(style))
43
- FileUtils.chmod(0644, path(style))
40
+ FileUtils.mkdir_p(File.dirname(path(style_name)))
41
+ log("saving #{path(style_name)}")
42
+ FileUtils.mv(file.path, path(style_name))
43
+ FileUtils.chmod(0644, path(style_name))
44
44
  end
45
45
  @queued_for_write = {}
46
46
  end
@@ -248,8 +248,8 @@ module Paperclip
248
248
  # distribution, and is integrated into the Limelight CDN. You can find out more about
249
249
  # it at http://www.rackspacecloud.com/cloud_hosting_products/files
250
250
  #
251
- # To install the Cloud Files gem, add the github gem source ("gem sources -a http://gems.github.com"), then
252
- # do a "gem install rackspace-cloudfiles". For more information, see the github repository at http://github.com/rackspace/ruby-cloudfiles/
251
+ # To install the Cloud Files gem, add the Gemcutter gem source ("gem sources -a http://gemcutter.org"), then
252
+ # do a "gem install cloudfiles". For more information, see the github repository at http://github.com/rackspace/ruby-cloudfiles/
253
253
  #
254
254
  # There are a few Cloud Files-specific options for has_attached_file:
255
255
  # * +cloudfiles_credentials+: Takes a path, a File, or a Hash. The path (or File) must point
@@ -293,7 +293,7 @@ module Paperclip
293
293
  @@cdn_url ||= cloudfiles_container.cdn_url
294
294
  @path_filename = ":cf_path_filename" unless @url.to_s.match(/^:cf.*filename$/)
295
295
  @url = @@cdn_url + "/#{URI.encode(@path_filename).gsub(/&/,'%26')}"
296
- @path = Paperclip::Attachment.default_options[:path] == @options[:path] ? ":attachment/:id/:style/:basename.:extension" : @options[:path]
296
+ @path = @options[:path] || ":attachment/:id/:style/:basename.:extension"
297
297
  end
298
298
  Paperclip.interpolates(:cf_path_filename) do |attachment, style|
299
299
  attachment.path(style)
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+ module Paperclip
3
+ # The Style class holds the definition of a thumbnail style, applying
4
+ # whatever processing is required to normalize the definition and delaying
5
+ # the evaluation of block parameters until useful context is available.
6
+
7
+ class Style
8
+
9
+ attr_reader :name, :attachment, :format
10
+
11
+ # Creates a Style object. +name+ is the name of the attachment,
12
+ # +definition+ is the style definition from has_attached_file, which
13
+ # can be string, array or hash
14
+ def initialize name, definition, attachment
15
+ @name = name
16
+ @attachment = attachment
17
+ if definition.is_a? Hash
18
+ @geometry = definition.delete(:geometry)
19
+ @format = definition.delete(:format)
20
+ @processors = definition.delete(:processors)
21
+ @other_args = definition
22
+ else
23
+ @geometry, @format = [definition, nil].flatten[0..1]
24
+ @other_args = {}
25
+ end
26
+ @format = nil if @format.blank?
27
+ end
28
+
29
+ # retrieves from the attachment the processors defined in the has_attached_file call
30
+ # (which method (in the attachment) will call any supplied procs)
31
+ # There is an important change of interface here: a style rule can set its own processors
32
+ # by default we behave as before, though.
33
+ def processors
34
+ @processors || attachment.processors
35
+ end
36
+
37
+ # retrieves from the attachment the whiny setting
38
+ def whiny
39
+ attachment.whiny
40
+ end
41
+
42
+ # returns true if we're inclined to grumble
43
+ def whiny?
44
+ !!whiny
45
+ end
46
+
47
+ def convert_options
48
+ attachment.send(:extra_options_for, name)
49
+ end
50
+
51
+ # returns the geometry string for this style
52
+ # if a proc has been supplied, we call it here
53
+ def geometry
54
+ @geometry.respond_to?(:call) ? @geometry.call(attachment.instance) : @geometry
55
+ end
56
+
57
+ # Supplies the hash of options that processors expect to receive as their second argument
58
+ # Arguments other than the standard geometry, format etc are just passed through from
59
+ # initialization and any procs are called here, just before post-processing.
60
+ def processor_options
61
+ args = {}
62
+ @other_args.each do |k,v|
63
+ args[k] = v.respond_to?(:call) ? v.call(attachment) : v
64
+ end
65
+ [:processors, :geometry, :format, :whiny, :convert_options].each do |k|
66
+ (arg = send(k)) && args[k] = arg
67
+ end
68
+ args
69
+ end
70
+
71
+ # Supports getting and setting style properties with hash notation to ensure backwards-compatibility
72
+ # eg. @attachment.styles[:large][:geometry]@ will still work
73
+ def [](key)
74
+ if [:name, :convert_options, :whiny, :processors, :geometry, :format].include?(key)
75
+ send(key)
76
+ elsif defined? @other_args[key]
77
+ @other_args[key]
78
+ end
79
+ end
80
+
81
+ def []=(key, value)
82
+ if [:name, :convert_options, :whiny, :processors, :geometry, :format].include?(key)
83
+ send("#{key}=".intern, value)
84
+ else
85
+ @other_args[key] = value
86
+ end
87
+ end
88
+
89
+ end
90
+ end
@@ -12,6 +12,7 @@ module Paperclip
12
12
  # set, the options will be appended to the convert command upon image conversion
13
13
  def initialize file, options = {}, attachment = nil
14
14
  super
15
+
15
16
  geometry = options[:geometry]
16
17
  @file = file
17
18
  @crop = geometry[-1,1] == '#'
@@ -24,6 +25,7 @@ module Paperclip
24
25
 
25
26
  @current_format = File.extname(@file.path)
26
27
  @basename = File.basename(@file.path, @current_format)
28
+
27
29
  end
28
30
 
29
31
  # Returns true if the +target_geometry+ is meant to crop.
data/lib/paperclip.rb CHANGED
@@ -34,6 +34,7 @@ require 'paperclip/processor'
34
34
  require 'paperclip/thumbnail'
35
35
  require 'paperclip/storage'
36
36
  require 'paperclip/interpolations'
37
+ require 'paperclip/style'
37
38
  require 'paperclip/attachment'
38
39
  if defined? RAILS_ROOT
39
40
  Dir.glob(File.join(File.expand_path(RAILS_ROOT), "lib", "paperclip_processors", "*.rb")).each do |processor|
@@ -45,7 +46,7 @@ end
45
46
  # documentation for Paperclip::ClassMethods for more useful information.
46
47
  module Paperclip
47
48
 
48
- VERSION = "2.3.1.1.0"
49
+ VERSION = "2.3.1.1.1"
49
50
 
50
51
  class << self
51
52
  # Provides configurability to Paperclip. There are a number of options available, such as:
@@ -239,7 +240,7 @@ module Paperclip
239
240
 
240
241
  validates_each(name) do |record, attr, value|
241
242
  attachment = record.attachment_for(name)
242
- attachment.send(:flush_errors) unless attachment.valid?
243
+ attachment.send(:flush_errors)
243
244
  end
244
245
  end
245
246
 
@@ -14,18 +14,6 @@ class AttachmentTest < Test::Unit::TestCase
14
14
  assert_equal "#{RAILS_ROOT}/public/fake_models/1234/fake", @attachment.path
15
15
  end
16
16
 
17
- should "call a proc sent to check_guard" do
18
- @dummy = Dummy.new
19
- @dummy.expects(:one).returns(:one)
20
- assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
21
- end
22
-
23
- should "call a method name sent to check_guard" do
24
- @dummy = Dummy.new
25
- @dummy.expects(:one).returns(:one)
26
- assert_equal :one, @dummy.avatar.send(:check_guard, :one)
27
- end
28
-
29
17
  context "Attachment default_options" do
30
18
  setup do
31
19
  rebuild_model
@@ -162,11 +150,6 @@ class AttachmentTest < Test::Unit::TestCase
162
150
  should "report the correct options when sent #extra_options_for(:large)" do
163
151
  assert_equal "-do_stuff", @dummy.avatar.send(:extra_options_for, :large)
164
152
  end
165
-
166
- before_should "call extra_options_for(:thumb/:large)" do
167
- Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:thumb)
168
- Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:large)
169
- end
170
153
  end
171
154
 
172
155
  context "An attachment with :convert_options that is a proc" do
@@ -194,11 +177,6 @@ class AttachmentTest < Test::Unit::TestCase
194
177
  should "report the correct options when sent #extra_options_for(:large)" do
195
178
  assert_equal "-all", @dummy.avatar.send(:extra_options_for, :large)
196
179
  end
197
-
198
- before_should "call extra_options_for(:thumb/:large)" do
199
- Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:thumb)
200
- Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:large)
201
- end
202
180
  end
203
181
 
204
182
  context "An attachment with :path that is a proc" do
@@ -267,10 +245,6 @@ class AttachmentTest < Test::Unit::TestCase
267
245
  @attachment = Dummy.new.avatar
268
246
  end
269
247
 
270
- should "not run the procs immediately" do
271
- assert_kind_of Proc, @attachment.styles[:normal][:geometry]
272
- end
273
-
274
248
  context "when assigned" do
275
249
  setup do
276
250
  @file = StringIO.new(".")
@@ -307,10 +281,6 @@ class AttachmentTest < Test::Unit::TestCase
307
281
  @attachment = Dummy.new.avatar
308
282
  end
309
283
 
310
- should "not run the proc immediately" do
311
- assert_kind_of Proc, @attachment.styles[:normal][:processors]
312
- end
313
-
314
284
  context "when assigned" do
315
285
  setup do
316
286
  @attachment.assign(StringIO.new("."))
@@ -354,19 +324,22 @@ class AttachmentTest < Test::Unit::TestCase
354
324
  setup { @dummy.avatar = @file }
355
325
 
356
326
  before_should "call #make on all specified processors" do
327
+ Paperclip::Thumbnail.expects(:make).with(any_parameters).returns(@file)
328
+ Paperclip::Test.expects(:make).with(any_parameters).returns(@file)
329
+ end
330
+
331
+ before_should "call #make with the right parameters passed as second argument" do
357
332
  expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => true, :convert_options => ""})
358
- Paperclip::Thumbnail.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
359
- Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
333
+ Paperclip::Thumbnail.expects(:make).with(anything, expected_params, anything).returns(@file)
360
334
  end
361
335
 
362
336
  before_should "call #make with attachment passed as third argument" do
363
- expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => true, :convert_options => ""})
364
- Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
337
+ Paperclip::Test.expects(:make).with(anything, anything, @dummy.avatar).returns(@file)
365
338
  end
366
339
  end
367
340
  end
368
341
 
369
- context "An attachment with no processors defined" do
342
+ context "An attachment with styles but no processors defined" do
370
343
  setup do
371
344
  rebuild_model :processors => [], :styles => {:something => 1}
372
345
  @dummy = Dummy.new
@@ -377,6 +350,17 @@ class AttachmentTest < Test::Unit::TestCase
377
350
  end
378
351
  end
379
352
 
353
+ context "An attachment without styles and with no processors defined" do
354
+ setup do
355
+ rebuild_model :processors => [], :styles => {}
356
+ @dummy = Dummy.new
357
+ @file = StringIO.new("...")
358
+ end
359
+ should "not raise when assigned to" do
360
+ @dummy.avatar = @file
361
+ end
362
+ end
363
+
380
364
  context "Assigning an attachment with post_process hooks" do
381
365
  setup do
382
366
  rebuild_model :styles => { :something => "100x100#" }
@@ -478,8 +462,6 @@ class AttachmentTest < Test::Unit::TestCase
478
462
  @attachment.expects(:valid_assignment?).with(@not_file).returns(true)
479
463
  @attachment.expects(:queue_existing_for_delete)
480
464
  @attachment.expects(:post_process)
481
- @attachment.expects(:valid?).returns(true)
482
- @attachment.expects(:validate)
483
465
  @dummy.avatar = @not_file
484
466
  end
485
467
 
@@ -498,6 +480,7 @@ class AttachmentTest < Test::Unit::TestCase
498
480
  FileUtils.rm_rf("tmp")
499
481
  rebuild_model
500
482
  @instance = Dummy.new
483
+ @instance.stubs(:id).returns 123
501
484
  @attachment = Paperclip::Attachment.new(:avatar, @instance)
502
485
  @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
503
486
  end
@@ -606,6 +589,7 @@ class AttachmentTest < Test::Unit::TestCase
606
589
  should "commit the files to disk" do
607
590
  [:large, :medium, :small].each do |style|
608
591
  io = @attachment.to_file(style)
592
+ # p "in commit to disk test, io is #{io.inspect} and @instance.id is #{@instance.id}"
609
593
  assert File.exists?(io)
610
594
  assert ! io.is_a?(::Tempfile)
611
595
  io.close
@@ -185,27 +185,6 @@ class PaperclipTest < Test::Unit::TestCase
185
185
  should "be valid" do
186
186
  assert @dummy.valid?
187
187
  end
188
-
189
- context "then has a validation added that makes it invalid" do
190
- setup do
191
- assert @dummy.save
192
- Dummy.class_eval do
193
- validates_attachment_content_type :avatar, :content_type => ["text/plain"]
194
- end
195
- @dummy2 = Dummy.find(@dummy.id)
196
- end
197
-
198
- should "be invalid when reloaded" do
199
- assert ! @dummy2.valid?, @dummy2.errors.inspect
200
- end
201
-
202
- should "be able to call #valid? twice without having duplicate errors" do
203
- @dummy2.avatar.valid?
204
- first_errors = @dummy2.avatar.errors
205
- @dummy2.avatar.valid?
206
- assert_equal first_errors, @dummy2.avatar.errors
207
- end
208
- end
209
188
  end
210
189
 
211
190
  context "a validation with an if guard clause" do
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+ require 'test/helper'
3
+
4
+ class StyleTest < Test::Unit::TestCase
5
+
6
+ context "A style rule" do
7
+ setup do
8
+ @attachment = attachment :path => ":basename.:extension",
9
+ :styles => { :foo => {:geometry => "100x100#", :format => :png} }
10
+ @style = @attachment.styles[:foo]
11
+ end
12
+
13
+ should "be held as a Style object" do
14
+ assert_kind_of Paperclip::Style, @style
15
+ end
16
+
17
+ should "get processors from the attachment definition" do
18
+ assert_equal [:thumbnail], @style.processors
19
+ end
20
+
21
+ should "have the right geometry" do
22
+ assert_equal "100x100#", @style.geometry
23
+ end
24
+
25
+ should "be whiny if the attachment is" do
26
+ @attachment.expects(:whiny).returns(true)
27
+ assert @style.whiny?
28
+ end
29
+
30
+ should "respond to hash notation" do
31
+ assert_equal [:thumbnail], @style[:processors]
32
+ assert_equal "100x100#", @style[:geometry]
33
+ end
34
+ end
35
+
36
+ context "A style rule with properties supplied as procs" do
37
+ setup do
38
+ @attachment = attachment :path => ":basename.:extension",
39
+ :whiny_thumbnails => true,
40
+ :processors => lambda {|a| [:test]},
41
+ :styles => {
42
+ :foo => lambda{|a| "300x300#"},
43
+ :bar => {
44
+ :geometry => lambda{|a| "300x300#"}
45
+ }
46
+ }
47
+ end
48
+
49
+ should "defer processing of procs until they are needed" do
50
+ assert_kind_of Proc, @attachment.styles[:foo].instance_variable_get("@geometry")
51
+ assert_kind_of Proc, @attachment.styles[:bar].instance_variable_get("@geometry")
52
+ assert_kind_of Proc, @attachment.instance_variable_get("@processors")
53
+ end
54
+
55
+ should "call procs when they are needed" do
56
+ assert_equal "300x300#", @attachment.styles[:foo].geometry
57
+ assert_equal "300x300#", @attachment.styles[:bar].geometry
58
+ assert_equal [:test], @attachment.styles[:foo].processors
59
+ assert_equal [:test], @attachment.styles[:bar].processors
60
+ end
61
+ end
62
+
63
+ context "An attachment with style rules in various forms" do
64
+ setup do
65
+ @attachment = attachment :path => ":basename.:extension",
66
+ :styles => {
67
+ :aslist => ["100x100", :png],
68
+ :ashash => {:geometry => "100x100", :format => :png},
69
+ :asstring => "100x100"
70
+ }
71
+ end
72
+ should "have the right number of styles" do
73
+ assert_kind_of Hash, @attachment.styles
74
+ assert_equal 3, @attachment.styles.size
75
+ end
76
+
77
+ should "have styles as Style objects" do
78
+ [:aslist, :ashash, :aslist].each do |s|
79
+ assert_kind_of Paperclip::Style, @attachment.styles[s]
80
+ end
81
+ end
82
+
83
+ should "have the right geometries" do
84
+ [:aslist, :ashash, :aslist].each do |s|
85
+ assert_equal @attachment.styles[s].geometry, "100x100"
86
+ end
87
+ end
88
+
89
+ should "have the right formats" do
90
+ assert_equal @attachment.styles[:aslist].format, :png
91
+ assert_equal @attachment.styles[:ashash].format, :png
92
+ assert_nil @attachment.styles[:asstring].format
93
+ end
94
+
95
+ end
96
+
97
+ context "An attachment with :convert_options" do
98
+ setup do
99
+ @attachment = attachment :path => ":basename.:extension",
100
+ :styles => {:thumb => "100x100", :large => "400x400"},
101
+ :convert_options => {:all => "-do_stuff", :thumb => "-thumbnailize"}
102
+ @style = @attachment.styles[:thumb]
103
+ @file = StringIO.new("...")
104
+ @file.stubs(:original_filename).returns("file.jpg")
105
+ end
106
+
107
+ before_should "not have called extra_options_for(:thumb/:large) on initialization" do
108
+ @attachment.expects(:extra_options_for).never
109
+ end
110
+
111
+ should "call extra_options_for(:thumb/:large) when convert options are requested" do
112
+ @attachment.expects(:extra_options_for).with(:thumb)
113
+ @attachment.styles[:thumb].convert_options
114
+ end
115
+ end
116
+
117
+ context "A style rule with its own :processors" do
118
+ setup do
119
+ @attachment = attachment :path => ":basename.:extension",
120
+ :styles => {
121
+ :foo => {
122
+ :geometry => "100x100#",
123
+ :format => :png,
124
+ :processors => [:test]
125
+ }
126
+ },
127
+ :processors => [:thumbnail]
128
+ @style = @attachment.styles[:foo]
129
+ end
130
+
131
+ should "not get processors from the attachment" do
132
+ @attachment.expects(:processors).never
133
+ assert_not_equal [:thumbnail], @style.processors
134
+ end
135
+
136
+ should "report its own processors" do
137
+ assert_equal [:test], @style.processors
138
+ end
139
+
140
+ end
141
+ end
@@ -200,7 +200,7 @@ class ThumbnailTest < Test::Unit::TestCase
200
200
  teardown { @file.close }
201
201
 
202
202
  should "start with two pages with dimensions 612x792" do
203
- cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
203
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
204
204
  assert_equal "612x792"*2, `#{cmd}`.chomp
205
205
  end
206
206
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-cloudfiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1.1.0
4
+ version: 2.3.1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Yurek
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-12-06 00:00:00 -06:00
13
+ date: 2010-01-27 00:00:00 -06:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -113,6 +113,7 @@ files:
113
113
  - lib/paperclip/matchers.rb
114
114
  - lib/paperclip/processor.rb
115
115
  - lib/paperclip/storage.rb
116
+ - lib/paperclip/style.rb
116
117
  - lib/paperclip/thumbnail.rb
117
118
  - lib/paperclip/upfile.rb
118
119
  - lib/paperclip.rb
@@ -139,6 +140,7 @@ files:
139
140
  - test/paperclip_test.rb
140
141
  - test/processor_test.rb
141
142
  - test/storage_test.rb
143
+ - test/style_test.rb
142
144
  - test/thumbnail_test.rb
143
145
  - test/upfile_test.rb
144
146
  - shoulda_macros/paperclip.rb