directwave 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENCE +9 -0
  6. data/README.md +318 -0
  7. data/Rakefile +20 -0
  8. data/directwave.gemspec +30 -0
  9. data/lib/directwave/mounter.rb +95 -0
  10. data/lib/directwave/orm/activerecord.rb +49 -0
  11. data/lib/directwave/railtie.rb +9 -0
  12. data/lib/directwave/uploader/accreditation.rb +63 -0
  13. data/lib/directwave/uploader/configuration.rb +68 -0
  14. data/lib/directwave/uploader/connection.rb +36 -0
  15. data/lib/directwave/uploader/paths.rb +51 -0
  16. data/lib/directwave/uploader/uploader.rb +54 -0
  17. data/lib/directwave/uploader/versions.rb +149 -0
  18. data/lib/directwave/version.rb +3 -0
  19. data/lib/directwave.rb +29 -0
  20. data/lib/generators/directwave_generator.rb +8 -0
  21. data/lib/generators/templates/directwave.rb +33 -0
  22. data/spec/.DS_Store +0 -0
  23. data/spec/directwave/.DS_Store +0 -0
  24. data/spec/directwave/fixtures/Uppercase.jpg +1 -0
  25. data/spec/directwave/fixtures/bork.ttxt +1 -0
  26. data/spec/directwave/fixtures/bork.txt +1 -0
  27. data/spec/directwave/fixtures/bork.txtt +1 -0
  28. data/spec/directwave/fixtures/case.JPG +1 -0
  29. data/spec/directwave/fixtures/landscape.jpg +0 -0
  30. data/spec/directwave/fixtures/new.jpeg +1 -0
  31. data/spec/directwave/fixtures/new.txt +1 -0
  32. data/spec/directwave/fixtures/old.jpeg +1 -0
  33. data/spec/directwave/fixtures/old.txt +1 -0
  34. data/spec/directwave/fixtures/portrait.jpg +0 -0
  35. data/spec/directwave/fixtures/sponsored.doc +1 -0
  36. data/spec/directwave/fixtures/test.jpeg +1 -0
  37. data/spec/directwave/fixtures/test.jpg +1 -0
  38. data/spec/directwave/fog.rb +0 -0
  39. data/spec/directwave/orm/active_record_spec.rb +8 -0
  40. data/spec/directwave/uploader/accreditation_spec.rb +42 -0
  41. data/spec/directwave/uploader/configuration_spec.rb +69 -0
  42. data/spec/directwave/uploader/connection_spec.rb +11 -0
  43. data/spec/directwave/uploader/paths_spec.rb +76 -0
  44. data/spec/directwave/uploader/uploader_spec.rb +33 -0
  45. data/spec/directwave/uploader/versions_spec.rb +88 -0
  46. data/spec/spec_helper.rb +19 -0
  47. metadata +200 -0
@@ -0,0 +1,36 @@
1
+ module DirectWave
2
+
3
+ module Uploader
4
+ module Connection
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ class_attribute :_s3_connection, :_s3_directory, :instance_reader => false, :instance_writer => false
8
+ end
9
+
10
+ module ClassMethods
11
+ # If no argument is given, it will simply return the currently used storage engine.
12
+ #
13
+ # === Parameters
14
+ #
15
+ # [storage (Symbol, Class)] The storage engine to use for this uploader
16
+ #
17
+ # === Returns
18
+ #
19
+ # [Class] the storage engine to be used with this uploader
20
+ def s3_connection
21
+ self._s3_connection ||= AWS::S3.new(
22
+ access_key_id: self.s3_access_key_id,
23
+ secret_access_key: self.s3_secret_access_key,
24
+ s3_endpoint: "s3-#{self.s3_region}.amazonaws.com"
25
+ )
26
+ end
27
+
28
+ def s3_directory
29
+ self._s3_directory ||= s3_connection.buckets[self.s3_bucket]
30
+ end
31
+ end # ClassMethods
32
+
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,51 @@
1
+ module DirectWave
2
+
3
+ module Uploader
4
+ module Paths
5
+ extend ActiveSupport::Concern
6
+
7
+ module InstanceMethods
8
+ def url(version=:original)
9
+ versions[version.to_sym].url || default_url
10
+ end
11
+
12
+ def key(version=:original)
13
+ versions[version.to_sym].key
14
+ end
15
+
16
+ def default_url
17
+ puts "default_url"
18
+ end
19
+
20
+ def filename(part=nil)
21
+ return original_filename unless has_store_key?
22
+
23
+ key_path = store_key.split("/")
24
+ filename_parts = []
25
+ filename = filename_parts.unshift(key_path.pop)
26
+ unique_key = key_path.pop
27
+ filename_parts.unshift(unique_key) if unique_key
28
+ filename_parts.join("/")
29
+ end
30
+
31
+ def original_filename
32
+ model[mounted_as.to_s] if model.respond_to?(mounted_as)
33
+ end
34
+
35
+ def store_key=(string)
36
+ @store_key = string
37
+ end
38
+
39
+ def store_key
40
+ @store_key ||= "#{upload_dir}/#{guid}/${filename}"
41
+ end
42
+
43
+ def has_store_key?
44
+ @store_key.present? && !(@store_key =~ /#{Regexp.escape("${filename}")}\z/)
45
+ end
46
+ end # InstanceMethods
47
+
48
+ end # Paths
49
+ end # Uploader
50
+
51
+ end
@@ -0,0 +1,54 @@
1
+ module DirectWave
2
+ module Uploader
3
+
4
+ class Base
5
+ include DirectWave::Uploader::Configuration
6
+ include DirectWave::Uploader::Accreditation
7
+ include DirectWave::Uploader::Paths
8
+ include DirectWave::Uploader::Versions
9
+ include DirectWave::Uploader::Connection
10
+
11
+ attr_reader :model, :mounted_as
12
+
13
+ def initialize(model=nil, mounted_as=nil)
14
+ @model = model
15
+ @mounted_as = mounted_as
16
+ end
17
+
18
+ def save
19
+ if has_store_key?
20
+ # at first remove previous files
21
+ versions.each { |name, version| version.delete } unless model[mounted_as].blank?
22
+
23
+ # at second process new files
24
+ model[mounted_as] = filename
25
+ versions.each { |name, version| version.process }
26
+ global_process
27
+ end
28
+ end
29
+
30
+ def destroy
31
+ versions.each { |name, version| version.delete }
32
+ end
33
+
34
+ def global_process; end
35
+
36
+ version :original do
37
+ def filename
38
+ @filename ||= [extract(:guid), extract(:basename) << extract(:extname)].join("/")
39
+ end
40
+
41
+ def process
42
+ super
43
+
44
+ source_file = @uploader.class.s3_directory.objects[@uploader.store_key]
45
+ destination_file = AWS::S3::S3Object.new(@uploader.class.s3_directory, key)
46
+
47
+ source_file.copy_to(destination_file, { acl: @uploader.s3_acl })
48
+ source_file.delete
49
+ end
50
+ end
51
+ end # Base
52
+
53
+ end # Uploader
54
+ end # DirectWave
@@ -0,0 +1,149 @@
1
+ module DirectWave
2
+
3
+ module Uploader
4
+ module Versions
5
+ class Version
6
+ def initialize(uploader, name)
7
+ @uploader = uploader
8
+ @name = name
9
+ end
10
+
11
+ def filename
12
+ @filename ||= [extract(:guid), [extract(:basename), @name].join("-") << extract(:extname)].join("/")
13
+ end
14
+
15
+ def url
16
+ @url ||= begin
17
+ if @uploader.s3_access_policy != :public_read
18
+ file.url_for(:get, { expires: @uploader.s3_authentication_timeout }).to_s
19
+ else
20
+ file.public_url.to_s
21
+ end
22
+ end
23
+ end
24
+
25
+ def key
26
+ @key ||= File.join([@uploader.store_dir, filename].compact)
27
+ end
28
+
29
+ def file
30
+ @file ||= @uploader.class.s3_directory.objects[key]
31
+ end
32
+
33
+ def process
34
+ @file = nil
35
+ @filename = nil
36
+ @url = nil
37
+ @key = nil
38
+ end
39
+
40
+ def delete
41
+ file.delete if file.exists?
42
+ end
43
+
44
+ private
45
+
46
+ def extract(part)
47
+ part = part.to_sym
48
+ key_path = @uploader.original_filename.split("/")
49
+ filename = key_path.pop
50
+ guid = key_path.pop
51
+
52
+ case part
53
+ when :guid
54
+ guid
55
+ when :basename
56
+ File.basename(filename, ".*")
57
+ when :extname
58
+ File.extname(filename)
59
+ else
60
+ filename
61
+ end
62
+ end
63
+
64
+ end # Version
65
+
66
+ extend ActiveSupport::Concern
67
+
68
+ included do
69
+ if respond_to?(:class_inheritable_accessor)
70
+ ActiveSupport::Deprecation.silence do
71
+ class_inheritable_accessor :versions, :instance_reader => false, :instance_writer => false
72
+ end
73
+ else
74
+ class_attribute :versions, :instance_reader => false, :instance_writer => false
75
+ end
76
+
77
+ self.versions = {}
78
+ end
79
+
80
+ module ClassMethods
81
+
82
+ ##
83
+ # Adds a new version to this uploader
84
+ #
85
+ # === Parameters
86
+ #
87
+ # [name (#to_sym)] name of the version
88
+ # [&block (Proc)] a block to eval on this version of the uploader
89
+ #
90
+ # === Examples
91
+ #
92
+ # class Video < DirectWave::Uploader::Base
93
+ #
94
+ # version :iphone do
95
+ # def filename
96
+ # @filename ||= [extract(:guid), "iphone-video" << extract(:extname)].join("/")
97
+ # end
98
+ #
99
+ # def process
100
+ # super
101
+ #
102
+ # # processing version here with zencoder.com or another encoding cloud service
103
+ # end
104
+ # end
105
+ #
106
+ # end
107
+ #
108
+ def version(name, &block)
109
+ name = name.to_sym
110
+ unless versions[name]
111
+ version = Class.new(Version)
112
+
113
+ # Add the current version hash to class attribute :versions
114
+ current_version = {}
115
+ current_version[name] = version
116
+ self.versions = versions.merge(current_version)
117
+
118
+ class_eval <<-RUBY
119
+ def #{name}
120
+ versions[:#{name}]
121
+ end
122
+ RUBY
123
+ end
124
+ versions[name].class_eval(&block) if block
125
+ versions[name]
126
+ end
127
+
128
+ end # ClassMethods
129
+
130
+ ##
131
+ # Returns a hash mapping the name of each version of the Version to an instance of it
132
+ #
133
+ # === Returns
134
+ #
135
+ # [Hash{Symbol => DirectWave::Versions::Version}] a list of version instances
136
+ #
137
+ def versions
138
+ return @versions if @versions
139
+ @versions = {}
140
+ self.class.versions.each do |name, version|
141
+ @versions[name] = version.new(self, name)
142
+ end
143
+ @versions
144
+ end
145
+
146
+ end # Versions
147
+ end # Uploader
148
+
149
+ end# DirectWave
@@ -0,0 +1,3 @@
1
+ module Directwave
2
+ VERSION = "0.0.1"
3
+ end
data/lib/directwave.rb ADDED
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ require "active_support/core_ext"
4
+ require "active_support/concern"
5
+ require "uuid"
6
+ require "aws-sdk"
7
+ require "base64"
8
+
9
+ module DirectWave
10
+ class << self
11
+ def configure(&block)
12
+ DirectWave::Uploader::Base.configure(&block)
13
+ end
14
+ end
15
+
16
+ autoload :Mounter, "directwave/mounter"
17
+ autoload :VERSION, "directwave/version"
18
+
19
+ module Uploader
20
+ autoload :Base, "directwave/uploader/uploader"
21
+ autoload :Configuration, "directwave/uploader/configuration"
22
+ autoload :Accreditation, "directwave/uploader/accreditation"
23
+ autoload :Paths, "directwave/uploader/paths"
24
+ autoload :Versions, "directwave/uploader/versions"
25
+ autoload :Connection, "directwave/uploader/connection"
26
+ end
27
+ end
28
+
29
+ require "directwave/railtie" if defined?(Rails)
@@ -0,0 +1,8 @@
1
+ class DirectwaveGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path("../templates", __FILE__)
3
+
4
+ def create_uploader_file
5
+ template "directwave.rb", "app/uploaders/#{file_name}_uploader.rb"
6
+ end
7
+ end
8
+
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ class <%= class_name %>Uploader < DirectWave::Uploader::Base
4
+ # Override the directory where uploaded files will be stored.
5
+ def store_dir
6
+ "uploads/#{model.class.to_s.underscore.pluralize}/#{mounted_as}"
7
+ end
8
+
9
+ # Override the directory where files will be uploaded.
10
+ def upload_dir
11
+ "uploads/tmp/#{Time.new.to_date.to_s}"
12
+ end
13
+
14
+ # Provide a default URL as a default if there hasn't been a file uploaded:
15
+ # def default_url
16
+ # # For Rails 3.1+ asset pipeline compatibility:
17
+ # # asset_path("fallback/default.ext")
18
+ #
19
+ # "fallback/default.ext"
20
+ # end
21
+ # Create different versions of your uploaded files:
22
+ # version :audio do
23
+ # def filename
24
+ # @filename ||= [extract(:guid), [extract(:basename), @name].join("-") << extract(:extname)].join("/")
25
+ # end
26
+ #
27
+ # def process
28
+ # super
29
+ #
30
+ # # processing code goes here
31
+ # end
32
+ # end
33
+ end
data/spec/.DS_Store ADDED
Binary file
Binary file
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ bork bork bork Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1 @@
1
+ Hi there
@@ -0,0 +1 @@
1
+ this is stuff
@@ -0,0 +1 @@
1
+ this is stuff
File without changes
@@ -0,0 +1,8 @@
1
+ require "spec_helper"
2
+ require "directwave/orm/activerecord"
3
+
4
+ describe DirectWave::ActiveRecord do
5
+ describe "activerecord" do
6
+ it "needs testing with rspec"
7
+ end
8
+ end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ describe DirectWave::Uploader::Accreditation do
4
+ before do
5
+ @model = mock("model")
6
+ @uploader_class = Class.new(DirectWave::Uploader::Base)
7
+ @uploader = @uploader_class.new(@model, "foo")
8
+ end
9
+
10
+ describe "#acl" do
11
+ it "should return the sanitized s3 access policy" do
12
+ @uploader.s3_acl.should == @uploader.s3_access_policy.to_s.gsub("_", "-")
13
+ end
14
+ end
15
+
16
+ describe "#policy" do
17
+ let(:decoded_s3_policy) { JSON.parse(Base64.decode64(@uploader.s3_policy)) }
18
+
19
+ it "should return Base64-encoded JSON" do
20
+ decoded_s3_policy.should be_a(Hash)
21
+ end
22
+
23
+ it "should not contain any new lines" do
24
+ @uploader.s3_policy.should_not include("\n")
25
+ end
26
+
27
+ it "should be tested by parts"
28
+ end
29
+
30
+ describe "#signature" do
31
+ it "should not contain any new lines" do
32
+ @uploader.s3_signature.should_not include("\n")
33
+ end
34
+
35
+ it "should return a base64 encoded 'sha1' hash of the secret key and policy document" do
36
+ Base64.decode64(@uploader.s3_signature).should == OpenSSL::HMAC.digest(
37
+ OpenSSL::Digest::Digest.new('sha1'),
38
+ @uploader.s3_secret_access_key, @uploader.s3_policy
39
+ )
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+
3
+ describe DirectWave do
4
+ before do
5
+ @uploader_class = Class.new(DirectWave::Uploader::Base)
6
+ end
7
+
8
+ describe '.configure' do
9
+ it "should proxy to Uploader configuration" do
10
+ DirectWave::Uploader::Base.add_config :test_config
11
+ DirectWave.configure do |config|
12
+ config.test_config = "foo"
13
+ end
14
+ DirectWave::Uploader::Base.test_config.should == 'foo'
15
+ end
16
+ end
17
+ end
18
+
19
+ describe DirectWave::Uploader::Base do
20
+ before do
21
+ @uploader_class = Class.new(DirectWave::Uploader::Base)
22
+ end
23
+
24
+ describe ".configure" do
25
+ it "should set a configuration parameter" do
26
+ @uploader_class.add_config :foo_bar
27
+ @uploader_class.configure do |config|
28
+ config.foo_bar = "monkey"
29
+ end
30
+ @uploader_class.foo_bar.should == "monkey"
31
+ end
32
+ end
33
+
34
+ describe ".add_config" do
35
+ it "should add a class level accessor" do
36
+ @uploader_class.add_config :foo_bar
37
+ @uploader_class.foo_bar = "foo"
38
+ @uploader_class.foo_bar.should == "foo"
39
+ end
40
+
41
+ ["foo", :foo, 45, ["foo", :bar]].each do |val|
42
+ it "should be inheritable for a #{val.class}" do
43
+ @uploader_class.add_config :foo_bar
44
+ @child_class = Class.new(@uploader_class)
45
+
46
+ @uploader_class.foo_bar = val
47
+ @uploader_class.foo_bar.should == val
48
+ @child_class.foo_bar.should == val
49
+
50
+ @child_class.foo_bar = "bar"
51
+ @child_class.foo_bar.should == "bar"
52
+
53
+ @uploader_class.foo_bar.should == val
54
+ end
55
+ end
56
+
57
+ it "should add an instance level accessor" do
58
+ @uploader_class.add_config :foo_bar
59
+ @uploader_class.foo_bar = "foo"
60
+ @uploader_class.new.foo_bar.should == "foo"
61
+ end
62
+
63
+ it "should add a convenient in-class setter" do
64
+ @uploader_class.add_config :foo_bar
65
+ @uploader_class.foo_bar "monkey"
66
+ @uploader_class.foo_bar.should == "monkey"
67
+ end
68
+ end # describe ".add_config"
69
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe DirectWave::Uploader::Connection do
4
+ describe ".s3_connection" do
5
+ it "not tested yet!"
6
+ end
7
+
8
+ describe ".s3_directory" do
9
+ it "not tested yet!"
10
+ end
11
+ end
@@ -0,0 +1,76 @@
1
+ require "spec_helper"
2
+
3
+ describe DirectWave::Uploader::Paths do
4
+ before do
5
+ @model = mock("a model object")
6
+ @uploader_class = Class.new(DirectWave::Uploader::Base)
7
+ @uploader = @uploader_class.new(@model, "foo")
8
+ end
9
+
10
+ describe '#original_filename' do
11
+ it "should return 'foo/bar.aac'" # @uploader.original_filename.should == "foo/bar.aac"
12
+ end
13
+
14
+ describe "#filename" do
15
+ context "store key is autogenerated" do
16
+ it "should return 'foo'" do
17
+ @uploader.filename.should be_nil
18
+ end
19
+ end
20
+
21
+ context "store key is key 's3/key/to/foo/bar.aac' of s3" do
22
+ before { @uploader.store_key = "s3/key/to/foo/bar.aac" }
23
+
24
+ it "should return 'foo/bar.aac'" do
25
+ @uploader.filename.should == "foo/bar.aac"
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "#store_key=" do
31
+ before { @uploader.store_key = "foo" }
32
+
33
+ it "should set the store key" do
34
+ @uploader.store_key.should == "foo"
35
+ end
36
+ end
37
+
38
+ describe "#store_key" do
39
+ context "where the store key is not set and #upload_dir returns 'foo'" do
40
+ before do
41
+ @uploader.stub(:upload_dir).and_return("foo")
42
+ @uploader.stub(:guid).and_return("guid")
43
+ @uploader.store_key = nil
44
+ end
45
+
46
+ it "should return 'foo/guid/${filename}'" do
47
+ @uploader.store_key.should =~ /foo\/guid\/\$\{filename\}$/
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "#has_store_key?" do
53
+ context "a store_key has not been set" do
54
+
55
+ it "should return false" do
56
+ @uploader.should_not have_store_key
57
+ end
58
+ end
59
+
60
+ context "the store_key has been autogenerated" do
61
+ before { @uploader.store_key }
62
+
63
+ it "should return false" do
64
+ @uploader.should_not have_store_key
65
+ end
66
+ end
67
+
68
+ context "the store_key has been set" do
69
+ before { @uploader.store_key = "foo" }
70
+
71
+ it "should return true" do
72
+ @uploader.should have_store_key
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,33 @@
1
+ describe DirectWave::Uploader do
2
+ before do
3
+ @model = mock('a model object')
4
+ @uploader_class = Class.new(DirectWave::Uploader::Base)
5
+ @uploader = @uploader_class.new(@model, :foo)
6
+ end
7
+
8
+ describe '#model' do
9
+ it "should be remembered from initialization" do
10
+ puts @uploader.store_key
11
+ @uploader.model.should == @model
12
+ end
13
+ end
14
+
15
+ describe '#mounted_as' do
16
+ it "should be remembered from initialization" do
17
+ @uploader.model.should == @model
18
+ @uploader.mounted_as.should == :foo
19
+ end
20
+ end
21
+
22
+ describe "#save" do
23
+ it "not tested yer and not finished"
24
+ end
25
+
26
+ describe "#destroy" do
27
+ it "not tested yer and not finished"
28
+ end
29
+
30
+ describe "#original version" do
31
+ it "not tested yer and not finished"
32
+ end
33
+ end