<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>FAQ</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -5,13 +5,6 @@ simpler, lighter alternative to
 attachment_fu[http://github.com/technoweenie/attachment_fu] for applications
 that need to handle uploaded images.
 
-It supports only filesystem storage, and uses only MiniMagick to process
-images. However, the codebase is very small, simple, readable, and hackable.
-So it should be pretty easy to modify or enhance its functionality.
-
-It works best for websites that want to create photo galleries with
-fixed-dimension thumbnails.
-
 It creates only one database record per image, requires only one column in
 your model, and creates great-looking fixed-dimension thumbnails by using
 {ImageMagick's}[http://www.imagemagick.org/]
@@ -20,8 +13,18 @@ crop[http://www.imagemagick.org/script/command-line-options.php#crop] and
 gravity[http://www.imagemagick.org/script/command-line-options.php#gravity]
 functions.
 
+Some typical use cases are: websites that want to create photo galleries with
+fixed-dimension thumbnails, or that want to store user profile pictures
+without creating a separate model for the images.
+
+It supports only filesystem storage, and uses only MiniMagick to process
+images. However, the codebase is very small, simple, readable, and hackable.
+So it should be easy to modify or enhance its functionality with different
+storage or processor options.
+
 == Another image attachment library? Why?
 
+&lt;em&gt;The three chief virtues of a programmer are: Laziness, Impatience and Hubris.&lt;/em&gt; - {Larry Wall}[http://en.wikipedia.org/wiki/Larry_Wall]
 
 Attachment_fu is too large and general for some of the places I want to use
 images. I sometimes found myself writing more code to hack attachment_fu than
@@ -33,16 +36,16 @@ various other reasons, so I decided to roll my own.
 
 == Examples
 
-Point-and-drool use case. Probably not what you want, but it may be useful for
-bootstrapping.
+Point-and-drool use case. It's probably not what you want, but it may be
+useful for bootstrapping.
 
-  class Photo &lt; ActiveRecord::Base
+  class Member &lt; ActiveRecord::Base
     has_image
   end
 
 Single image, no thumbnails, with some size limits:
 
-  class Photo &lt; ActiveRecord::Base
+  class Picture &lt; ActiveRecord::Base
     has_image :resize_to =&gt; &quot;200x200&quot;,
       :max_size =&gt; 3.megabytes,
       :min_size =&gt; 4.kilobytes
@@ -62,8 +65,8 @@ Image with some thumbnails:
 
 == Getting it
 
-Has image is designed to work with Rails 2.1 and is installed via Ruby Gems;
-no need for a plugin. To use it in your app, install the gem:
+Has image is designed to work with Rails 2.1 and is installed via Ruby Gems,
+not as a plugin. To use it in your application, install the gem:
 
   gem install norman-has_image --source http://gems.github.com
 
@@ -77,7 +80,7 @@ Then, make sure the model you want to use it in has a column named &quot;file_name.&quot;
 
 {Git repository}[http://github.com/norman/has_image]: 
 
-  http://github.com/norman/has_image
+  git://github.com/norman/has_image.git
 
 
 == Hacking it
@@ -94,17 +97,23 @@ logo? Happiness is just a monkey-patch away:
     end
   end
 
-HasImage[http://github.com/norman/has_image] follows a philosophy of &quot;skinny
-model, fat plugin.&quot; This means that it tries to pollute your ActiveRecord
-model with as little functionality as possible, so that in a sense, the model
-is acts like a &quot;controller&quot; and the plugin like a &quot;model&quot; as regards the image
-handling functionality. This makes it easier to test, hack, and port to other
-frameworks, because the storage and processing functionality is largely
-independent of your model.
+HasImage[http://github.com/norman/has_image] follows a philosophy of &quot;{skinny
+model, fat plugin}[http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model].&quot;
+This means that it tries to pollute your ActiveRecord model with as little
+functionality as possible, so that in a sense, the model is acts like a
+&quot;controller&quot; and the plugin like a &quot;model&quot; as regards the image handling
+functionality. This makes it easier to test, hack, and reuse, because the
+storage and processing functionality is largely independent of your model, and
+of Rails.
+
+My goal for HasImage[http://github.com/norman/has_image] is to keep it very
+small. If you need a lot of functionality that's not here, you will likely be
+better off using attachment_fu[http://github.com/technoweenie/attachment_fu],
+which is much more powerful, but also more complex.
 
 At the time of writing (July 2008),
 HasImage[http://github.com/norman/has_image] is in its infancy. Your patches,
-bug reports and withering criticm is more than welcome.
+bug reports and withering criticism are more than welcome.
 
 Copyright (c) 2008 {Norman Clarke}[mailto:norman@randomba.org], released under
 the MIT license
\ No newline at end of file</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -39,7 +39,8 @@ desc 'Generate documentation for has_image.'
 Rake::RDocTask.new(:rdoc) do |rdoc|
   rdoc.rdoc_dir = 'rdoc'
   rdoc.title    = 'HasImage'
-  rdoc.options &lt;&lt; '--line-numbers' &lt;&lt; '--inline-source'
+  rdoc.options &lt;&lt; '--line-numbers' &lt;&lt; '--inline-source' &lt;&lt; '-c UTF-8'
   rdoc.rdoc_files.include('README')
+  rdoc.rdoc_files.include('FAQ')
   rdoc.rdoc_files.include('lib/**/*.rb')
 end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,16 +1,17 @@
 Gem::Specification.new do |s|
   s.name = &quot;has_image&quot;
   s.version = &quot;0.1.0&quot;
-  s.date = &quot;2008-07-21&quot;
+  s.date = &quot;2008-07-23&quot;
   s.summary = &quot;Lets you attach images with thumbnails to active record models.&quot;
   s.email = 'norman@randomba.org'
   s.homepage = 'http://randomba.org'
-  s.description = 'HasImage is a gem/plugin for Rails for attached images, like a super-lightweight attachment_fu for images only.'
+  s.description = 'HasImage is a Ruby on Rails gem/plugin that allows you to attach images to ActiveRecord models.'
   s.has_rdoc = true
   s.authors = ['Norman Clarke']
   s.files = [
     &quot;MIT-LICENSE&quot;,
     &quot;README&quot;,
+    &quot;FAQ&quot;,
     &quot;init.rb&quot;,
     &quot;lib/has_image.rb&quot;,
     &quot;lib/has_image/processor.rb&quot;,</diff>
      <filename>has_image.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -4,21 +4,24 @@ require 'has_image/storage'
 # = HasImage
 #
 # HasImage allows Ruby on Rails applications to have attached images. It is very
-# small and lightweight: it only requires only one column (by default,
-# &quot;file_name&quot;) in your model to store the uploaded image's file name.
+# small and lightweight: it only requires one column (by default, &quot;file_name&quot;)
+# in your model to store the uploaded image's file name.
 # 
 # HasImage is, by design, very simplistic: It only supports using a filesystem
 # for storage, and only supports
 # MiniMagick[http://github.com/probablycorey/mini_magick] as an image processor.
 # However, its code is very small, clean and hackable, so adding support for
-# other backends or processors should be possible.
+# other backends or processors should be fairly easy.
 # 
 # HasImage works best for sites that want to show image galleries with
-# fixed-size thumbnails. It uses ImageMagick's crop and center gravity functions
-# to produce thumbnails that generally look acceptable, unless the image is a
-# panorama, or the subject matter is close to one of the margins, etc. For most
-# sites where people upload pictures of themselves or their pets the generated
-# thumbnails will look good almost all the time.
+# fixed-size thumbnails. It uses ImageMagick's
+# crop[http://www.imagemagick.org/script/command-line-options.php#crop] and
+# {center
+# gravity}[http://www.imagemagick.org/script/command-line-options.php#gravity]
+# functions to produce thumbnails that generally look acceptable, unless the
+# image is a panorama, or the subject matter is close to one of the margins,
+# etc. For most sites where people upload pictures of themselves or their pets
+# the generated thumbnails will look good almost all the time.
 # 
 # It's pretty easy to change the image processing / resizing code; you can just
 # override HasImage::Processor#resize_image to do what you wish:
@@ -61,6 +64,8 @@ module HasImage
 
   class ProcessorError &lt; StandardError ; end
   class StorageError &lt; StandardError ; end  
+  class FileTooBigError &lt; StorageError ; end  
+  class FileTooSmallError &lt; StorageError ; end  
   
   class &lt;&lt; self
     def included(base) # :nodoc:
@@ -69,37 +74,86 @@ module HasImage
 
     # Enables has_image functionality. You probably don't need to ever invoke
     # this.
-    def enable
+    def enable # :nodoc:
       return if ActiveRecord::Base.respond_to? :has_image
       ActiveRecord::Base.send(:include, HasImage)    
     end
+
+    # If you're invoking this method, you need to pass in the class for which
+    # you want to get default options; this is used to determine the path where
+    # the images will be stored in the file system. Take a look at
+    # HasImage::ClassMethods#has_image to see examples of how to set the options
+    # in your model.
+    #
+    # This method is called by your model when you call has_image. It's
+    # placed here rather than in the model's class methods to make it easier
+    # to access for testing. Unless you're working on the code, it's unlikely
+    # you'll ever need to invoke this method.
+    #
+    # * :resize_to =&gt; &quot;200x200&quot;,
+    # * :thumbnails =&gt; {},
+    # * :max_size =&gt; 12.megabytes,
+    # * :min_size =&gt; 4.kilobytes,
+    # * :path_prefix =&gt; klass.to_s.tableize,
+    # * :base_path =&gt; File.join(RAILS_ROOT, 'public'),
+    # * :convert_to =&gt; &quot;JPEG&quot;,
+    # * :output_quality =&gt; &quot;85&quot;,
+    # * :invalid_image_message =&gt; &quot;Can't process the image.&quot;,
+    # * :image_too_small_message =&gt; &quot;The image is too small.&quot;,
+    # * :image_too_big_message =&gt; &quot;The image is too big.&quot;,
+    # * :file_name_column =&gt; :file_name
+    def default_options_for(klass)
+      {
+        :resize_to =&gt; &quot;200x200&quot;,
+        :thumbnails =&gt; {},
+        :max_size =&gt; 12.megabytes,
+        :min_size =&gt; 4.kilobytes,
+        :path_prefix =&gt; klass.to_s.tableize,
+        :base_path =&gt; File.join(RAILS_ROOT, 'public'),
+        :convert_to =&gt; &quot;JPEG&quot;,
+        :output_quality =&gt; &quot;85&quot;,
+        :invalid_image_message =&gt; &quot;Can't process the image.&quot;,
+        :image_too_small_message =&gt; &quot;The image is too small.&quot;,
+        :image_too_big_message =&gt; &quot;The image is too big.&quot;,
+        :file_name_column =&gt; :file_name
+      }
+    end
+    
   end
 
   module ClassMethods
-    
+    # To use HasImage with a Rails model, you must make sure you have a column
+    # for storing the attached file's name. This defaults to &quot;file_name,&quot;
+    # but can be overridden by setting the option described below. This is the
+    # only column you need to add to your model. You might want to take a look
+    # at the default options specified in HasImage#default_options_for.
+    #
     # Options:
-    # *  &lt;tt&gt;:resize_to&lt;/tt&gt; - Dimensions to resize to. This should be an ImageMagick geometry string. Fixed sizes are recommended.
-    # *  &lt;tt&gt;:thumbnails&lt;/tt&gt; - A hash of thumbnail names and sizes. The sizes should be ImageMagick geometry strings. Fixed sized are recommended.
-    # *  &lt;tt&gt;:min_size&lt;/tt&gt; - Minimum size allowed.
-    # *  &lt;tt&gt;:max_size&lt;/tt&gt; - Maximum size allowed.
+    # *  &lt;tt&gt;:resize_to&lt;/tt&gt; - Dimensions to resize to. This should be an ImageMagick {geometry string}[http://www.imagemagick.org/script/command-line-options.php#resize]. Fixed sizes are recommended.
+    # *  &lt;tt&gt;:thumbnails&lt;/tt&gt; - A hash of thumbnail names and dimensions. The dimensions should be ImageMagick {geometry strings}[http://www.imagemagick.org/script/command-line-options.php#resize]. Fixed sized are recommended.
+    # *  &lt;tt&gt;:min_size&lt;/tt&gt; - Minimum file size allowed. It's recommended that you set this size in kilobytes.
+    # *  &lt;tt&gt;:max_size&lt;/tt&gt; - Maximum file size allowed. It's recommended that you set this size in megabytes.
     # *  &lt;tt&gt;:base_path&lt;/tt&gt; - Where to install the images. You should probably leave this alone, except for tests.
     # *  &lt;tt&gt;:path_prefix&lt;/tt&gt; - Where to install the images, relative to basepath. You should probably leave this alone.
     # *  &lt;tt&gt;:convert_to&lt;/tt&gt; - An ImageMagick format to convert images to. Recommended formats: JPEG, PNG, GIF.
     # *  &lt;tt&gt;:output_quality&lt;/tt&gt; - Image output quality passed to ImageMagick.
-    # *  &lt;tt&gt;:invalid_image_message&lt;/tt&gt; - The message that will be shown on validation errors.
+    # *  &lt;tt&gt;:invalid_image_message&lt;/tt&gt; - The message that will be shown when the image data can't be processed.
+    # *  &lt;tt&gt;:image_too_small_message&lt;/tt&gt; - The message that will be shown when the image file is too small. You should ideally set this to something that tells the user what the minimum is.
+    # *  &lt;tt&gt;:image_too_big_message&lt;/tt&gt; - The message that will be shown when the image file is too big. You should ideally set this to something that tells the user what the maximum is.
     # *  &lt;tt&gt;:file_name_column&lt;/tt&gt; - The column that the file name will be saved in.
     #
     # Examples:
-    #   has_image
+    #   has_image # uses all default options
     #   has_image :resize_to &quot;800x800&quot;, :thumbnails =&gt; {:square =&gt; &quot;150x150&quot;}
     #   has_image :resize_to &quot;100x150&quot;, :max_size =&gt; 500.kilobytes, :file_name_column =&gt; &quot;avatar&quot;
+    #   has_image :invalid_image_message =&gt; &quot;No se puede procesar la imagen.&quot;
     def has_image(options = {})
       options.assert_valid_keys(:resize_to, :thumbnails, :max_size, :min_size,
         :path_prefix, :base_path, :convert_to, :output_quality,
         :invalid_image_message, :file_name_column)
-      options = default_has_image_options.merge(options)
+      options = HasImage.default_options_for(self).merge(options)
+      class_inheritable_accessor :has_image_options
       write_inheritable_attribute(:has_image_options, options)
-      class_inheritable_reader :has_image_options
       
       attr_accessible :image_data
       
@@ -113,31 +167,6 @@ module HasImage
     
     end
     
-    # * &lt;tt&gt;:resize_to&lt;/tt&gt; - 200x200
-    # * &lt;tt&gt;:thumbnails&lt;/tt&gt; - {}
-    # * &lt;tt&gt;:max_size&lt;/tt&gt; - 12.megabytes
-    # * &lt;tt&gt;:min_size&lt;/tt&gt; - 4.kilobytes
-    # * &lt;tt&gt;:path_prefix&lt;/tt&gt; - #{table_name}
-    # * &lt;tt&gt;:base_path&lt;/tt&gt; - #{RAILS_ROOT}/public
-    # * &lt;tt&gt;:convert_to&lt;/tt&gt; - JPEG
-    # * &lt;tt&gt;:output_quality&lt;/tt&gt; - 85
-    # * &lt;tt&gt;:invalid_image_message&lt;/tt&gt; - &quot;Can't process the uploaded image.&quot;
-    # * &lt;tt&gt;:file_name_column&lt;/tt&gt; - :file_name
-    def default_has_image_options
-      {
-        :resize_to =&gt; &quot;200x200&quot;,
-        :thumbnails =&gt; {},
-        :max_size =&gt; 12.megabytes,
-        :min_size =&gt; 4.kilobytes,
-        :path_prefix =&gt; table_name,
-        :base_path =&gt; File.join(RAILS_ROOT, 'public'),
-        :convert_to =&gt; &quot;JPEG&quot;,
-        :output_quality =&gt; &quot;85&quot;,
-        :invalid_image_message =&gt; &quot;Can't process the uploaded image.&quot;,
-        :file_name_column =&gt; :file_name
-      }
-    end
-
   end
 
   module ModelInstanceMethods
@@ -147,7 +176,11 @@ module HasImage
     end
     
     def image_data_valid?
-      if !HasImage::Processor.valid?(storage.temp_file)
+      if storage.image_too_big?
+        errors.add_to_base(self.class.has_image_options[:image_too_big_message])
+      elsif storage.image_too_small?
+        errors.add_to_base(self.class.has_image_options[:image_too_small_message])
+      elsif !HasImage::Processor.valid?(storage.temp_file)
         errors.add_to_base(self.class.has_image_options[:invalid_image_message])
       end
     end
@@ -165,7 +198,7 @@ module HasImage
     end
     
     def storage
-      @storage ||= HasImage::Storage.new(self.has_image_options)
+      @storage ||= HasImage::Storage.new(has_image_options)
     end
     
   end</diff>
      <filename>lib/has_image.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,12 +21,14 @@ module HasImage
       end    
     end
 
-    def initialize(options)
+    # The constuctor should be invoked with the options set by has_image.
+    def initialize(options) # :nodoc:
       @options = options
     end
     
     # Create the resized image, and transforms it to the desired output
-    # format if necessary.
+    # format if necessary. The size should be a valid ImageMagick {geometry
+    # string}[http://www.imagemagick.org/script/command-line-options.php#resize].
     def resize(file, size)
       silence_stderr do
         path = file.respond_to?(:path) ? file.path : file
@@ -42,6 +44,13 @@ module HasImage
     
     # Image resizing is placed in a separate method for easy monkey-patching.
     # This is intended to be invoked from resize, rather than directly.
+    # By default, the following ImageMagick functionality is invoked:
+    # * auto-orient[http://www.imagemagick.org/script/command-line-options.php#auto-orient]
+    # * strip[http://www.imagemagick.org/script/command-line-options.php#strip]
+    # * resize[http://www.imagemagick.org/script/command-line-options.php#resize]
+    # * gravity[http://www.imagemagick.org/script/command-line-options.php#gravity]
+    # * extent[http://www.imagemagick.org/script/command-line-options.php#extent]
+    # * quality[http://www.imagemagick.org/script/command-line-options.php#quality]
     def resize_image(size)
       @image.combine_options do |commands|
         commands.send(&quot;auto-orient&quot;.to_sym)</diff>
      <filename>lib/has_image/processor.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,7 @@ module HasImage
         (&quot;%08d&quot; % id).scan(/..../) + args
       end
 
-      # Generates an 8-character random file name to use for the image and its
+      # Generates an 6-character random file name to use for the image and its
       # thumbnails. This is done to avoid having files with unfortunate names.
       # On one of my sites users frequently upload images with Arabic names,
       # and they end up being hard to manipulate on the command line.
@@ -30,7 +30,8 @@ module HasImage
           
     end
 
-    def initialize(options)
+    # The constuctor should be invoked with the options set by has_image.
+    def initialize(options) # :nodoc:
       @options = options
     end
 
@@ -47,6 +48,18 @@ module HasImage
         @temp_file.write(image_data.read)        
       end
     end
+
+    # Is uploaded file smaller than the allowed minimum?
+    def image_too_small?
+      @temp_file.open if @temp_file.closed?
+      @temp_file.size &lt; options[:min_size]
+    end
+    
+    # Is uploaded file larger than the allowed maximum?
+    def image_too_big?
+      @temp_file.open if @temp_file.closed?
+      @temp_file.size &gt; options[:max_size]
+    end
     
     # A tip of the hat to attachment_fu.
     alias uploaded_data= image_data=
@@ -66,13 +79,15 @@ module HasImage
     end
     
     # Gets the full local filesystem path for an image. For example:
-    # /var/sites/example.com/production/public/photos/0000/0001/3eRdh0zs.jpg
+    #
+    #   /var/sites/example.com/production/public/photos/0000/0001/3er0zs.jpg
     def filesystem_path_for(object, thumbnail = nil)
       File.join(path_for(object.id), file_name_for(object.file_name, thumbnail))
     end
     
     # Gets the &quot;web&quot; path for an image. For example:
-    # /photos/0000/0001/3eRdh0zs.jpg
+    #
+    #   /photos/0000/0001/3er0zs.jpg
     def public_path_for(object, thumbnail = nil)
       filesystem_path_for(object, thumbnail).gsub(options[:base_path], '')
     end
@@ -81,17 +96,34 @@ module HasImage
     def remove_images(id)
       FileUtils.rm_r path_for(id)
     end
+
+    # Is the uploaded file within the min and max allowed sizes?
+    def valid?
+      !(image_too_small? || image_too_big?)
+    end
     
     private
     
+    # Gets the extension to append to the image. Transforms &quot;jpeg&quot; to &quot;jpg.&quot;
     def extension
       options[:convert_to].to_s.downcase.gsub(&quot;jpeg&quot;, &quot;jpg&quot;)
     end
 
+    # File name, plus thumbnail suffix, plus extension. For example:
+    #
+    #   file_name_for(&quot;abc123&quot;, :thumb)
+    #
+    # gives you:
+    #
+    #   &quot;abc123_thumb.jpg&quot;
+    #   
+    #
     def file_name_for(*args)
       &quot;%s.%s&quot; % [args.compact.join(&quot;_&quot;), extension]
     end
     
+    # Write the main image to the install directory - probably somewhere under
+    # RAILS_ROOT/public.
     def install_main_image(id, name)
       FileUtils.mkdir_p path_for(id)
       main = processor.resize(@temp_file, @options[:resize_to])
@@ -99,6 +131,8 @@ module HasImage
       main.tempfile.close!
     end
     
+    # Write the thumbnails to the install directory - probably somewhere under
+    # RAILS_ROOT/public.
     def install_thumbnails(id, name)
       FileUtils.mkdir_p path_for(id)
       path = File.join(path_for(id), file_name_for(name))
@@ -109,10 +143,16 @@ module HasImage
       end
     end
     
+    # Get the full path for the id. For example:
+    #
+    #  /var/sites/example.org/production/public/photos/0000/0001
     def path_for(id)
       File.join(options[:base_path], options[:path_prefix], Storage.partitioned_path(id))
     end
     
+    # Instantiates the processor using the options set in my contructor (if
+    # not already instantiated), stores it in an instance variable, and
+    # returns it.
     def processor
       @processor ||= Processor.new(options)
     end</diff>
      <filename>lib/has_image/storage.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,34 +7,26 @@ class StorageTest &lt; Test::Unit::TestCase
   
   def teardown
     FileUtils.rm_rf(File.dirname(__FILE__) + '/../tmp')
+    @temp_file.close! if @temp_file &amp;&amp; !@temp_file.closed?
   end
   
   def default_options
-    {
-      :resize_to =&gt; &quot;300x270&quot;,
-      :thumbnails =&gt; {
-        :square =&gt; &quot;75x75&quot;,
-      },
-      :max_size =&gt; 3.megabytes,
-      :min_size =&gt; 4.kilobytes,
-      :path_prefix =&gt; &quot;tests&quot;,
-      :base_path =&gt; File.join(File.dirname(__FILE__), '..', 'tmp'),
-      :convert_to =&gt; &quot;JPEG&quot;,
-      :output_quality =&gt; &quot;85&quot;
-    }
+    HasImage.default_options_for(&quot;tests&quot;).merge(
+      :base_path =&gt; File.join(File.dirname(__FILE__), '..', 'tmp')
+    )
   end
   
   def test_partitioned_path
-    assert HasImage::Storage.partitioned_path(&quot;12345&quot;)
+    assert_equal([&quot;0001&quot;, &quot;2345&quot;], HasImage::Storage.partitioned_path(&quot;12345&quot;))
   end
   
   def test_random_file_name
-    assert HasImage::Storage.random_file_name
+    assert_match(/[a-z0-9]{4,6}/i, HasImage::Storage.random_file_name)
   end
   
   def test_path_for
     @storage = HasImage::Storage.new(default_options)
-    assert_not_nil @storage.send(:path_for, 1)
+    assert_match(/\/tmp\/tests\/0000\/0001/, @storage.send(:path_for, 1))
   end
   
   def test_public_path_for
@@ -54,32 +46,53 @@ class StorageTest &lt; Test::Unit::TestCase
     @storage.image_data = @file
     assert @storage.temp_file.size &gt; 0
     assert_equal Zlib.crc32(@file.read), Zlib.crc32(@storage.temp_file.read)
-  ensure
-    @storage.temp_file.close!
   end
   
   def test_set_data_from_tempfile
     @storage = HasImage::Storage.new(default_options)
-    @file = File.new(File.dirname(__FILE__) + &quot;/fixtures/image.jpg&quot;, &quot;r&quot;)
-    @temp_file = Tempfile.new(&quot;test&quot;)
-    @temp_file.write(@file.read)
-    @storage.image_data = @temp_file
+    @storage.image_data = temp_file(&quot;image.jpg&quot;)
     assert @storage.temp_file.size &gt; 0
     assert_equal Zlib.crc32(@storage.temp_file.read), Zlib.crc32(@temp_file.read)
-  ensure
-    @temp_file.close!
   end
   
   def test_install_and_remove_images
     @storage = HasImage::Storage.new(default_options)
-    @file = File.new(File.dirname(__FILE__) + &quot;/fixtures/image.jpg&quot;, &quot;r&quot;)
-    @temp_file = Tempfile.new(&quot;test&quot;)
-    @temp_file.write(@file.read)
-    @storage.image_data = @temp_file
+    @storage.image_data = temp_file(&quot;image.jpg&quot;)
     assert @storage.install_images(1)
     assert @storage.remove_images(1)    
-  ensure
-    @temp_file.close!
   end
 
+  def test_image_not_too_small
+    @storage = HasImage::Storage.new(default_options.merge(:min_size =&gt; 1.kilobyte))
+    @storage.image_data = temp_file(&quot;image.jpg&quot;)
+    assert !@storage.image_too_small?
+  end
+  
+  def test_image_too_small
+    @storage = HasImage::Storage.new(default_options.merge(:min_size =&gt; 1.gigabyte))
+    @storage.image_data = temp_file(&quot;image.jpg&quot;)
+    assert @storage.image_too_small?
+  end
+  
+  def test_image_too_big
+    @storage = HasImage::Storage.new(default_options.merge(:max_size =&gt; 1.kilobyte))
+    @storage.image_data = temp_file(&quot;image.jpg&quot;)    
+    assert @storage.image_too_big?
+  end
+
+  def test_image_not_too_big
+    @storage = HasImage::Storage.new(default_options.merge(:max_size =&gt; 1.gigabyte))
+    @storage.image_data = temp_file(&quot;image.jpg&quot;)    
+    assert !@storage.image_too_big?
+  end
+  
+  private
+  
+  def temp_file(fixture)
+    file = File.new(File.dirname(__FILE__) + &quot;/fixtures/#{fixture}&quot;, &quot;r&quot;)
+    @temp_file = Tempfile.new(&quot;test&quot;)
+    @temp_file.write(file.read)
+    return @temp_file
+  end
+  
 end
\ No newline at end of file</diff>
      <filename>test/storage_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,3 +2,5 @@ require 'test/unit'
 require 'rubygems'
 require 'mocha'
 require 'has_image'
+
+RAILS_ROOT = File.join(File.dirname(__FILE__), '..', 'tmp')</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,7 @@ require 'test_helper'
 class PicTest &lt; Test::Unit::TestCase
   
   def setup
+    Pic.has_image_options = HasImage.default_options_for(Pic)
     Pic.has_image_options[:base_path] = File.join(RAILS_ROOT, '/tmp')
   end
   
@@ -13,7 +14,21 @@ class PicTest &lt; Test::Unit::TestCase
   def test_should_be_valid
     image = &quot;/../../test/fixtures/image.jpg&quot;
     @pic = Pic.new(:image_data =&gt; fixture_file_upload(image, &quot;image/jpeg&quot;))
-    assert @pic.valid?
+    assert @pic.valid? , &quot;#{@pic.errors.full_messages.to_sentence}&quot;
+  end
+
+  def test_should_be_too_big
+    Pic.has_image_options[:max_size] = 1.kilobyte
+    image = &quot;/../../test/fixtures/image.jpg&quot;
+    @pic = Pic.new(:image_data =&gt; fixture_file_upload(image, &quot;image/jpeg&quot;))
+    assert !@pic.valid?
+  end
+
+  def test_should_be_too_small
+    Pic.has_image_options[:min_size] = 1.gigabyte
+    image = &quot;/../../test/fixtures/image.jpg&quot;
+    @pic = Pic.new(:image_data =&gt; fixture_file_upload(image, &quot;image/jpeg&quot;))
+    assert !@pic.valid?
   end
 
   def test_invalid_image_detected
@@ -25,15 +40,22 @@ class PicTest &lt; Test::Unit::TestCase
   def test_create
     image = &quot;/../../test/fixtures/image.jpg&quot;
     @pic = Pic.new(:image_data =&gt; fixture_file_upload(image, &quot;image/jpeg&quot;))
-    @pic.save!
+    assert @pic.save!
   end
 
   def test_create_with_png
     image = &quot;/../../test/fixtures/image.png&quot;
+    Pic.has_image_options[:min_size] = 1
     @pic = Pic.new(:image_data =&gt; fixture_file_upload(image, &quot;image/png&quot;))
-    assert @pic.valid?
-    @pic.save!
+    assert @pic.save!
   end
 
+  def test_multiple_calls_to_valid_doesnt_blow_away_temp_image
+    image = &quot;/../../test/fixtures/image.png&quot;
+    Pic.has_image_options[:min_size] = 1
+    @pic = Pic.new(:image_data =&gt; fixture_file_upload(image, &quot;image/png&quot;))
+    @pic.valid?
+    assert @pic.valid?
+  end
   
 end
\ No newline at end of file</diff>
      <filename>test_rails/pic_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>52be8869bff94d584a288b81468fab33c3c8818e</id>
    </parent>
  </parents>
  <author>
    <name>Norman Clarke</name>
    <email>norman@addthree.com</email>
  </author>
  <url>http://github.com/norman/has_image/commit/7c1ac7c53faa21cfa1fbdb507f1b6f2d5d63f00e</url>
  <id>7c1ac7c53faa21cfa1fbdb507f1b6f2d5d63f00e</id>
  <committed-date>2008-07-24T12:00:17-07:00</committed-date>
  <authored-date>2008-07-24T12:00:17-07:00</authored-date>
  <message>Implemented uploaded file size checking. Improved documentation. Other minor
code cleanups.</message>
  <tree>ca3cd4c6a46561fa01cdbf7adc539d3ec021f189</tree>
  <committer>
    <name>Norman Clarke</name>
    <email>norman@addthree.com</email>
  </committer>
</commit>
