Skip to content

Commit

Permalink
Extract from CarrierWave
Browse files Browse the repository at this point in the history
  • Loading branch information
jnicklas committed May 18, 2011
0 parents commit ca96eb0
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
@@ -0,0 +1,6 @@
pkg/*
*.gem
.bundle
spec/public
.rvmrc
Gemfile.lock
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source "http://rubygems.org"

# Specify your gem's dependencies in carrierwave-datamapper.gemspec
gemspec
12 changes: 12 additions & 0 deletions Rakefile
@@ -0,0 +1,12 @@
require 'bundler'
Bundler::GemHelper.install_tasks

require 'rspec/core/rake_task'

desc "Run all examples"
RSpec::Core::RakeTask.new(:spec) do |t|
#t.rspec_path = 'bin/rspec'
t.rspec_opts = %w[--color]
end

task :default => :spec
28 changes: 28 additions & 0 deletions carrierwave-datamapper.gemspec
@@ -0,0 +1,28 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "carrierwave/datamapper/version"

Gem::Specification.new do |s|
s.name = "carrierwave-datamapper"
s.version = Carrierwave::Datamapper::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Jonas Nicklas", "Trevor Turk"]
s.email = ["jonas.nicklas@gmail.com"]
s.homepage = "https://github.com/jnicklas/carrierwave-datamapper"
s.summary = %q{Datamapper support for CarrierWave}
s.description = %q{Datamapper support for CarrierWave}

s.rubyforge_project = "carrierwave-datamapper"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_dependency "dm-core", ["~> 1.0"]
s.add_dependency "carrierwave"
s.add_development_dependency "rspec", ["~> 2.0"]
s.add_development_dependency "dm-validations", ["~> 1.0"]
s.add_development_dependency "dm-migrations", ["~> 1.0"]
s.add_development_dependency "dm-sqlite-adapter", ["~> 1.0"]
end
37 changes: 37 additions & 0 deletions lib/carrierwave/datamapper.rb
@@ -0,0 +1,37 @@
# encoding: utf-8

require 'dm-core'

module CarrierWave
module DataMapper

include CarrierWave::Mount

##
# See +CarrierWave::Mount#mount_uploader+ for documentation
#
def mount_uploader(column, uploader, options={}, &block)
super

alias_method :read_uploader, :attribute_get
alias_method :write_uploader, :attribute_set
after :save, "store_#{column}!".to_sym
pre_hook = ::DataMapper.const_defined?(:Validate) ? :valid? : :save
before pre_hook, "write_#{column}_identifier".to_sym
after :destroy, "remove_#{column}!".to_sym

# FIXME: Hack to work around Datamapper not triggering callbacks
# for objects that are not dirty. By explicitly calling
# attribute_set we are marking the record as dirty.
class_eval <<-RUBY
def remove_#{column}=(value)
_mounter(:#{column}).remove = value
attribute_set(:#{column}, '') if _mounter(:#{column}).remove?
end
RUBY
end

end # DataMapper
end # CarrierWave

DataMapper::Model.send(:include, CarrierWave::DataMapper)
5 changes: 5 additions & 0 deletions lib/carrierwave/datamapper/version.rb
@@ -0,0 +1,5 @@
module Carrierwave
module Datamapper
VERSION = "0.1.0"
end
end
169 changes: 169 additions & 0 deletions spec/datamapper_spec.rb
@@ -0,0 +1,169 @@
# encoding: utf-8

require 'spec_helper'

require 'dm-core'
require 'dm-validations'
require 'dm-migrations'
require 'carrierwave/orm/datamapper'

DataMapper.setup(:default, 'sqlite3::memory:')

describe CarrierWave::DataMapper do

before do
uploader = Class.new(CarrierWave::Uploader::Base)

@class = Class.new
@class.class_eval do
include DataMapper::Resource

storage_names[:default] = 'events'

property :id, DataMapper::Property::Serial

# auto validation off currently for inferred type
# validation. issue is that validations are done on
# the value returned by model#property_name which is overloaded
# by carrierwave. pull request in @dm-more to remedy this.
property :image, String, :auto_validation => false

mount_uploader :image, uploader
end

@class.auto_migrate!

@uploader = uploader

@event = @class.new
end

describe '#image' do

it "should return blank uploader when nothing has been assigned" do
@event.image.should be_blank
end

it "should return blank uploader when an empty string has been assigned" do
repository(:default).adapter.execute("INSERT INTO events (image) VALUES ('')")
@event = @class.first

@event.image.should be_blank
end

it "should retrieve a file from the storage if a value is stored in the database" do
repository(:default).adapter.execute("INSERT INTO events (image) VALUES ('test.jpg')")
@event = @class.first

@event.save
@event.reload
@event.image.should be_an_instance_of(@uploader)
end

it "should set the path to the store dir" do
@event.attribute_set(:image, 'test.jpeg')
@event.save
@event.reload
@event.image.current_path.should == public_path('uploads/test.jpeg')
end

end

describe '#image=' do

it "should cache a file" do
@event.image = stub_file('test.jpeg')
@event.image.should be_an_instance_of(@uploader)
end

it "should write nothing to the database, to prevent overriden filenames to fail because of unassigned attributes" do
@event.attribute_get(:image).should be_nil
end

it "should copy a file into into the cache directory" do
@event.image = stub_file('test.jpeg')
@event.image.current_path.should =~ /^#{public_path('uploads/tmp')}/
end

it "should do nothing when nil is assigned" do
@event.image = nil
@event.image.should be_blank
end

it "should do nothing when an empty string is assigned" do
@event.image = ''
@event.image.should be_blank
end

end

describe '#save' do

it "should do nothing when no file has been assigned" do
@event.save
@event.image.should be_blank
end

it "should copy the file to the upload directory when a file has been assigned" do
@event.image = stub_file('test.jpeg')
@event.save
@event.image.should be_an_instance_of(@uploader)
@event.image.current_path.should == public_path('uploads/test.jpeg')
end

it "should assign the filename to the database" do
@event.image = stub_file('test.jpeg')
@event.save
@event.reload
@event.attribute_get(:image).should == 'test.jpeg'
end

it "should remove the image if remove_image? returns true" do
@event.image = stub_file('test.jpeg')
@event.save
@event.remove_image = true
@event.save
@event.reload
@event.image.should be_blank
@event.attribute_get(:image).should == ''
end

describe "with validations" do
it "should do nothing when a validation fails" do
@class.validates_with_block(:textfile) { [false, "FAIL!"] }
@event.image = stub_file('test.jpeg')
@event.save
@event.image.should be_an_instance_of(@uploader)
@event.image.current_path.should =~ /^#{public_path('uploads/tmp')}/
end

it "should assign the filename before validation" do
@class.validates_with_block(:image) { [false, "FAIL!"] if self.image.nil? }
@event.image = stub_file('test.jpeg')
@event.save
@event.reload
@event.attribute_get(:image).should == 'test.jpeg'
end
end

end

describe '#destroy' do

it "should do nothing when no file has been assigned" do
@event.destroy
end

it "should remove the file from the filesystem" do
@event.image = stub_file('test.jpeg')
@event.save.should be_true
File.exist?(public_path('uploads/test.jpeg')).should be_true
@event.image.should be_an_instance_of(@uploader)
@event.image.current_path.should == public_path('uploads/test.jpeg')
@event.destroy
File.exist?(public_path('uploads/test.jpeg')).should be_false
end

end

end
1 change: 1 addition & 0 deletions spec/fixtures/test.jpeg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions spec/spec_helper.rb
@@ -0,0 +1,30 @@
require 'rubygems'
require 'bundler/setup'
require 'rspec'

require 'carrierwave'

def file_path( *paths )
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', *paths))
end

def public_path( *paths )
File.expand_path(File.join(File.dirname(__FILE__), 'public', *paths))
end

CarrierWave.root = public_path

module CarrierWave
module Test
module MockFiles
def stub_file(filename, mime_type=nil, fake_name=nil)
f = File.open(file_path(filename))
return f
end
end
end
end

RSpec.configure do |config|
config.include CarrierWave::Test::MockFiles
end

0 comments on commit ca96eb0

Please sign in to comment.