|
require 'rspec/rails' |
|
require 'carrierwave' |
|
|
|
module CarrierWave::Test::UploaderExampleGroup |
|
extend ActiveSupport::Concern |
|
|
|
include RSpec::Rails::RailsExampleGroup |
|
include CarrierWave::Test::Matchers |
|
|
|
included do |
|
subject { version_name.nil? ? uploader : uploader.send(version_name) } |
|
|
|
metadata[:type] = :uploader |
|
end |
|
|
|
module ClassMethods |
|
[:model_class, :mounted_as, :version_name].each do |name| |
|
define_method name do |value=nil| |
|
metadata[name] = value unless value.nil? |
|
metadata[name] |
|
end |
|
|
|
define_method "#{name}=" do |value| |
|
metadata[name] = value |
|
end |
|
end |
|
|
|
# Allow easily describing versions |
|
def describe *args |
|
if args.first.is_a? Symbol and described_class.include? CarrierWave::Uploader::Versions and described_class.versions.include? args.first |
|
name = args.shift |
|
options = args.extract_options! |
|
super "#{name} version", *args, options.reverse_merge(:version_name => name) |
|
else |
|
super |
|
end |
|
end |
|
end |
|
|
|
# The following methods are fairly interdependent. As a rule, don't use methods beneath the current. |
|
|
|
def model_class value=nil |
|
self.model_class = value unless value.nil? |
|
|
|
@_model_class ||= begin |
|
metadata = example.metadata |
|
|
|
model_inferred = false |
|
|
|
# TODO: infer smarter. MyModelMyColumnUploader? Split by word and check class name / mounted as combinations, complain on ambiguity. |
|
|
|
metadata[:model_class] ||= begin |
|
if described_class.name =~ /Uploader$/ |
|
model_inferred = true |
|
described_class.name.sub /Uploader$/, "" |
|
else |
|
raise NameError, "Can't infer uploader model name from uploader named #{described_class.name}. Set with `describe model_class: MyModel`" |
|
end |
|
end |
|
|
|
unless metadata[:model_class].is_a? Class |
|
metadata[:model_class] = metadata[:model_class].to_s |
|
begin |
|
metadata[:model_class] = metadata[:model_class].constantize |
|
rescue NameError |
|
classified = metadata[:model_class].classify |
|
classified_different = metadata[:model_class] != classified |
|
|
|
if not classified_different |
|
raise NameError, "No class named #{metadata[:model_class]}#{" (inferred from uploader name, use `describe model_class: MyModel` to set explicitly)" if model_inferred}" |
|
else |
|
begin |
|
metadata[:model_class] = classified.constantize |
|
rescue NameError |
|
raise NameError, "No class named #{metadata[:model_class]} or #{classified}#{" (inferred from uploader name, use `describe model_class: MyModel` to set explicitly)" if model_inferred}" |
|
end |
|
end |
|
end |
|
end |
|
|
|
metadata[:model_class].tap do |model_class| |
|
unless CarrierWave::Mount === model_class |
|
raise TypeError, "#{model_class.name} is not a carrierwave mounting class (wrong class name or not configured yet?)" |
|
end |
|
|
|
unless model_class.uploaders.any? { |name, uploader| uploader == described_class } |
|
raise StandardError, "#{model_class.name} has not mounted #{described_class.name} as an uploader" |
|
end |
|
end |
|
end |
|
end |
|
|
|
def model_class= value |
|
@_model_class = nil |
|
example.metadata[:model_class] = value |
|
end |
|
|
|
def mounted_as value=nil |
|
self.mounted_as = value unless value.nil? |
|
|
|
@_mounted_as ||= begin |
|
metadata = example.metadata |
|
|
|
metadata[:mounted_as] ||= metadata[:model_class].uploaders.select { |name, uploader| uploader == described_class }.first.first |
|
|
|
metadata[:mounted_as] = metadata[:mounted_as].to_sym if metadata[:mounted_as].is_a? String |
|
|
|
metadata[:mounted_as].tap do |mounted_as| |
|
unless model_class.uploaders.has_key? mounted_as |
|
raise NameError, "#{model_class.name} does not have an uploader mounted as #{mounted_as}" |
|
end |
|
|
|
unless model_class.uploaders[mounted_as] == described_class |
|
raise TypeError, "Uploader mounted on #{model_class.name} as #{mounted_as} is not a #{described_class.name}" |
|
end |
|
end |
|
end |
|
end |
|
|
|
def mounted_as= value |
|
@_mounted_as = nil |
|
example.metadata[:mounted_as] = value |
|
end |
|
|
|
def model |
|
example.metadata[:model] ||= model_class.new |
|
end |
|
|
|
def version_name value=nil |
|
self.version_name = value unless value.nil? |
|
@_version_name ||= begin |
|
example.metadata[:version_name].tap do |version_name| |
|
raise NameError, "No version named #{version_name.inspect} for #{described_class.name}" unless version_name.nil? or described_class.versions.has_key? version_name |
|
end |
|
end |
|
end |
|
|
|
def version_name= value |
|
@_version_name = nil |
|
example.metadata[:version_name] = value |
|
end |
|
|
|
def uploader_class |
|
described_class |
|
end |
|
|
|
def uploader |
|
@_uploader ||= uploader_class.new model, mounted_as |
|
end |
|
end |
|
|
|
RSpec::configure do |config| |
|
# XXX: Should disabling processing be optional? |
|
|
|
config.before :all do |example| |
|
CarrierWave::Uploader::Base.enable_processing = false |
|
end |
|
|
|
config.before :all, :type => :uploader do |
|
described_class.enable_processing = true |
|
end |
|
|
|
config.after :all, :type => :uploader do |
|
described_class.enable_processing = false |
|
end |
|
|
|
config.include CarrierWave::Test::UploaderExampleGroup, :type => :uploader, :example_group => { |
|
:file_path => %r{spec[\\\/]uploaders} |
|
} |
|
|
|
# TODO: how to spec anonymous uploaders? In model example group, describe symbol named after uploader column? |
|
end |