fog-dragonfly 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fog-dragonfly might be problematic. Click here for more details.
- data/.specopts +2 -0
- data/.yardopts +23 -0
- data/Gemfile +23 -0
- data/Gemfile.rails.2.3.5 +14 -0
- data/History.md +266 -0
- data/LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +92 -0
- data/VERSION +1 -0
- data/config.ru +13 -0
- data/docs.watchr +1 -0
- data/dragonfly.gemspec +293 -0
- data/extra_docs/Analysers.md +108 -0
- data/extra_docs/Caching.md +23 -0
- data/extra_docs/Configuration.md +138 -0
- data/extra_docs/DataStorage.md +136 -0
- data/extra_docs/Encoding.md +96 -0
- data/extra_docs/GeneralUsage.md +121 -0
- data/extra_docs/Generators.md +102 -0
- data/extra_docs/Heroku.md +50 -0
- data/extra_docs/Index.md +36 -0
- data/extra_docs/MimeTypes.md +40 -0
- data/extra_docs/Models.md +266 -0
- data/extra_docs/Mongo.md +45 -0
- data/extra_docs/Processing.md +130 -0
- data/extra_docs/Rack.md +52 -0
- data/extra_docs/Rails2.md +55 -0
- data/extra_docs/Rails3.md +62 -0
- data/extra_docs/Sinatra.md +25 -0
- data/extra_docs/URLs.md +169 -0
- data/features/3.0.3.feature +8 -0
- data/features/images.feature +47 -0
- data/features/no_processing.feature +14 -0
- data/features/rails_2.3.5.feature +7 -0
- data/features/steps/common_steps.rb +8 -0
- data/features/steps/dragonfly_steps.rb +66 -0
- data/features/steps/rails_steps.rb +39 -0
- data/features/support/env.rb +40 -0
- data/fixtures/files/app/models/album.rb +3 -0
- data/fixtures/files/app/views/albums/new.html.erb +4 -0
- data/fixtures/files/app/views/albums/show.html.erb +4 -0
- data/fixtures/files/config/initializers/dragonfly.rb +4 -0
- data/fixtures/files/features/manage_album_images.feature +12 -0
- data/fixtures/files/features/step_definitions/image_steps.rb +15 -0
- data/fixtures/files/features/support/paths.rb +15 -0
- data/fixtures/files/features/text_images.feature +7 -0
- data/fixtures/rails_2.3.5/template.rb +10 -0
- data/fixtures/rails_3.0.3/template.rb +20 -0
- data/irbrc.rb +17 -0
- data/lib/dragonfly.rb +45 -0
- data/lib/dragonfly/active_model_extensions.rb +13 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +169 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +45 -0
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
- data/lib/dragonfly/active_model_extensions/validations.rb +37 -0
- data/lib/dragonfly/analyser.rb +59 -0
- data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
- data/lib/dragonfly/analysis/image_magick_analyser.rb +47 -0
- data/lib/dragonfly/analysis/r_magick_analyser.rb +63 -0
- data/lib/dragonfly/app.rb +182 -0
- data/lib/dragonfly/config/heroku.rb +19 -0
- data/lib/dragonfly/config/image_magick.rb +41 -0
- data/lib/dragonfly/config/r_magick.rb +46 -0
- data/lib/dragonfly/config/rails.rb +17 -0
- data/lib/dragonfly/configurable.rb +119 -0
- data/lib/dragonfly/core_ext/object.rb +8 -0
- data/lib/dragonfly/core_ext/string.rb +9 -0
- data/lib/dragonfly/core_ext/symbol.rb +9 -0
- data/lib/dragonfly/data_storage.rb +9 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +114 -0
- data/lib/dragonfly/data_storage/mongo_data_store.rb +82 -0
- data/lib/dragonfly/data_storage/s3data_store.rb +115 -0
- data/lib/dragonfly/encoder.rb +13 -0
- data/lib/dragonfly/encoding/image_magick_encoder.rb +57 -0
- data/lib/dragonfly/encoding/r_magick_encoder.rb +61 -0
- data/lib/dragonfly/function_manager.rb +69 -0
- data/lib/dragonfly/generation/hash_with_css_style_keys.rb +23 -0
- data/lib/dragonfly/generation/image_magick_generator.rb +140 -0
- data/lib/dragonfly/generation/r_magick_generator.rb +155 -0
- data/lib/dragonfly/generator.rb +9 -0
- data/lib/dragonfly/image_magick_utils.rb +81 -0
- data/lib/dragonfly/job.rb +371 -0
- data/lib/dragonfly/job_builder.rb +39 -0
- data/lib/dragonfly/job_definitions.rb +26 -0
- data/lib/dragonfly/job_endpoint.rb +15 -0
- data/lib/dragonfly/loggable.rb +28 -0
- data/lib/dragonfly/middleware.rb +34 -0
- data/lib/dragonfly/processing/image_magick_processor.rb +99 -0
- data/lib/dragonfly/processing/r_magick_processor.rb +126 -0
- data/lib/dragonfly/processor.rb +9 -0
- data/lib/dragonfly/r_magick_utils.rb +48 -0
- data/lib/dragonfly/rails/images.rb +22 -0
- data/lib/dragonfly/response.rb +82 -0
- data/lib/dragonfly/routed_endpoint.rb +40 -0
- data/lib/dragonfly/serializer.rb +32 -0
- data/lib/dragonfly/simple_cache.rb +23 -0
- data/lib/dragonfly/simple_endpoint.rb +63 -0
- data/lib/dragonfly/temp_object.rb +220 -0
- data/samples/beach.png +0 -0
- data/samples/egg.png +0 -0
- data/samples/round.gif +0 -0
- data/samples/sample.docx +0 -0
- data/samples/taj.jpg +0 -0
- data/spec/argument_matchers.rb +19 -0
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +723 -0
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
- data/spec/dragonfly/analyser_spec.rb +123 -0
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +57 -0
- data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +15 -0
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +27 -0
- data/spec/dragonfly/analysis/shared_analyser_spec.rb +51 -0
- data/spec/dragonfly/app_spec.rb +280 -0
- data/spec/dragonfly/config/r_magick_spec.rb +25 -0
- data/spec/dragonfly/configurable_spec.rb +220 -0
- data/spec/dragonfly/core_ext/string_spec.rb +17 -0
- data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
- data/spec/dragonfly/data_storage/data_store_spec.rb +76 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +169 -0
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +38 -0
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +94 -0
- data/spec/dragonfly/deprecation_spec.rb +20 -0
- data/spec/dragonfly/encoding/image_magick_encoder_spec.rb +41 -0
- data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +37 -0
- data/spec/dragonfly/function_manager_spec.rb +154 -0
- data/spec/dragonfly/generation/hash_with_css_style_keys_spec.rb +24 -0
- data/spec/dragonfly/generation/image_magick_generator_spec.rb +12 -0
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +24 -0
- data/spec/dragonfly/generation/shared_generator_spec.rb +91 -0
- data/spec/dragonfly/image_magick_utils_spec.rb +16 -0
- data/spec/dragonfly/job_builder_spec.rb +37 -0
- data/spec/dragonfly/job_definitions_spec.rb +35 -0
- data/spec/dragonfly/job_endpoint_spec.rb +120 -0
- data/spec/dragonfly/job_spec.rb +773 -0
- data/spec/dragonfly/loggable_spec.rb +80 -0
- data/spec/dragonfly/middleware_spec.rb +68 -0
- data/spec/dragonfly/processing/image_magick_processor_spec.rb +29 -0
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +26 -0
- data/spec/dragonfly/processing/shared_processing_spec.rb +215 -0
- data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
- data/spec/dragonfly/serializer_spec.rb +61 -0
- data/spec/dragonfly/simple_cache_spec.rb +27 -0
- data/spec/dragonfly/simple_endpoint_spec.rb +89 -0
- data/spec/dragonfly/temp_object_spec.rb +352 -0
- data/spec/image_matchers.rb +47 -0
- data/spec/simple_matchers.rb +44 -0
- data/spec/spec_helper.rb +58 -0
- data/yard/handlers/configurable_attr_handler.rb +38 -0
- data/yard/setup.rb +15 -0
- data/yard/templates/default/fulldoc/html/css/common.css +107 -0
- data/yard/templates/default/layout/html/layout.erb +87 -0
- data/yard/templates/default/module/html/configuration_summary.erb +31 -0
- data/yard/templates/default/module/setup.rb +17 -0
- metadata +550 -0
data/samples/beach.png
ADDED
Binary file
|
data/samples/egg.png
ADDED
Binary file
|
data/samples/round.gif
ADDED
Binary file
|
data/samples/sample.docx
ADDED
Binary file
|
data/samples/taj.jpg
ADDED
Binary file
|
@@ -0,0 +1,19 @@
|
|
1
|
+
def string_matching(regexp)
|
2
|
+
Spec::Mocks::ArgumentMatchers::RegexpMatcher.new(regexp)
|
3
|
+
end
|
4
|
+
|
5
|
+
class TempObjectArgumentMatcher
|
6
|
+
def initialize(data, opts)
|
7
|
+
@data = data
|
8
|
+
@opts = opts
|
9
|
+
end
|
10
|
+
def ==(actual)
|
11
|
+
actual.is_a?(Dragonfly::TempObject) &&
|
12
|
+
actual.data == @data &&
|
13
|
+
@opts.all?{|k,v| actual.send(k) == v }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def a_temp_object_with_data(data, opts={})
|
18
|
+
TempObjectArgumentMatcher.new(data, opts)
|
19
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# --------------------------------------------------------------- #
|
2
|
+
# MODELS
|
3
|
+
# --------------------------------------------------------------- #
|
4
|
+
class MyModel
|
5
|
+
|
6
|
+
# Callbacks
|
7
|
+
extend ActiveModel::Callbacks
|
8
|
+
define_model_callbacks :save, :destroy
|
9
|
+
|
10
|
+
include ActiveModel::Validations
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def create!(attrs={})
|
14
|
+
new(attrs).save!
|
15
|
+
end
|
16
|
+
|
17
|
+
def find(id)
|
18
|
+
new(instances[id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def instances
|
22
|
+
@instances ||= {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(attrs={})
|
27
|
+
attrs.each do |key, value|
|
28
|
+
send("#{key}=", value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :id
|
33
|
+
|
34
|
+
def to_hash
|
35
|
+
self.class::ATTRIBUTES.inject({}) do |hash, attr|
|
36
|
+
hash[attr] = send(attr)
|
37
|
+
hash
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def save
|
42
|
+
_run_save_callbacks {
|
43
|
+
self.id ||= rand(1000)
|
44
|
+
self.class.instances[id] = self.to_hash
|
45
|
+
}
|
46
|
+
end
|
47
|
+
def save!
|
48
|
+
save
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy
|
53
|
+
_run_destroy_callbacks {}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Item < MyModel
|
58
|
+
|
59
|
+
ATTRIBUTES = [
|
60
|
+
:title,
|
61
|
+
:preview_image_uid,
|
62
|
+
:preview_image_some_analyser_method,
|
63
|
+
:preview_image_size,
|
64
|
+
:preview_image_name,
|
65
|
+
:preview_image_ext,
|
66
|
+
:preview_image_blah_blah,
|
67
|
+
:other_image_uid,
|
68
|
+
:yet_another_image_uid,
|
69
|
+
:otra_imagen_uid,
|
70
|
+
:trailer_video_uid,
|
71
|
+
:created_at,
|
72
|
+
:updated_at
|
73
|
+
]
|
74
|
+
attr_accessor *ATTRIBUTES
|
75
|
+
end
|
76
|
+
|
77
|
+
class Car < MyModel
|
78
|
+
ATTRIBUTES = [
|
79
|
+
:image_uid,
|
80
|
+
:reliant_image_uid,
|
81
|
+
:type
|
82
|
+
]
|
83
|
+
attr_accessor *ATTRIBUTES
|
84
|
+
end
|
85
|
+
|
86
|
+
class Photo < MyModel
|
87
|
+
ATTRIBUTES = [:image_uid]
|
88
|
+
attr_accessor *ATTRIBUTES
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# --------------------------------------------------------------- #
|
93
|
+
# HELPER METHODS
|
94
|
+
# --------------------------------------------------------------- #
|
95
|
+
def model_class
|
96
|
+
MyModel
|
97
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Seems to blow up on Rails 3 without this - only need temporarily
|
2
|
+
begin
|
3
|
+
require 'active_support/all'
|
4
|
+
rescue LoadError => e
|
5
|
+
puts "Couldn't load activesupport: #{e}"
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'active_record'
|
9
|
+
|
10
|
+
# --------------------------------------------------------------- #
|
11
|
+
# MIGRATION
|
12
|
+
# --------------------------------------------------------------- #
|
13
|
+
class MigrationForTest < ActiveRecord::Migration
|
14
|
+
|
15
|
+
def self.up
|
16
|
+
create_table :items, :force => true do |t|
|
17
|
+
t.string :title
|
18
|
+
t.string :preview_image_uid
|
19
|
+
t.string :preview_image_some_analyser_method
|
20
|
+
t.integer :preview_image_size
|
21
|
+
t.string :preview_image_name
|
22
|
+
t.string :preview_image_ext
|
23
|
+
t.string :preview_image_blah_blah
|
24
|
+
t.string :other_image_uid
|
25
|
+
t.string :yet_another_image_uid
|
26
|
+
t.string :otra_imagen_uid
|
27
|
+
t.string :trailer_video_uid
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
|
31
|
+
create_table :cars do |t|
|
32
|
+
t.string :image_uid
|
33
|
+
t.string :reliant_image_uid
|
34
|
+
t.string :type
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table :photos do |t|
|
38
|
+
t.string :image_uid
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.down
|
44
|
+
drop_table :items
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# --------------------------------------------------------------- #
|
51
|
+
# MODELS
|
52
|
+
# --------------------------------------------------------------- #
|
53
|
+
class Item < ActiveRecord::Base
|
54
|
+
end
|
55
|
+
class Car < ActiveRecord::Base
|
56
|
+
end
|
57
|
+
class Photo < ActiveRecord::Base
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# --------------------------------------------------------------- #
|
62
|
+
# SPEC CONFIG
|
63
|
+
# --------------------------------------------------------------- #
|
64
|
+
DB_FILE = File.expand_path(File.dirname(__FILE__)+'/db.sqlite3')
|
65
|
+
|
66
|
+
Spec::Runner.configure do |config|
|
67
|
+
|
68
|
+
config.before(:all) do
|
69
|
+
FileUtils.rm_f(DB_FILE)
|
70
|
+
ActiveRecord::Base.establish_connection(
|
71
|
+
:adapter => "sqlite3",
|
72
|
+
:database => DB_FILE
|
73
|
+
)
|
74
|
+
MigrationForTest.verbose = false
|
75
|
+
MigrationForTest.up
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
# --------------------------------------------------------------- #
|
81
|
+
# HELPER METHODS
|
82
|
+
# --------------------------------------------------------------- #
|
83
|
+
def model_class
|
84
|
+
ActiveRecord::Base
|
85
|
+
end
|
@@ -0,0 +1,723 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Item do
|
4
|
+
|
5
|
+
# See extra setup in models / initializer files
|
6
|
+
|
7
|
+
describe "defining accessors" do
|
8
|
+
|
9
|
+
let(:app1){ Dragonfly[:images] }
|
10
|
+
let(:app2){ Dragonfly[:videos] }
|
11
|
+
|
12
|
+
it "should return the mapping of apps to attributes" do
|
13
|
+
app1.define_macro(model_class, :image_accessor)
|
14
|
+
app2.define_macro(model_class, :video_accessor)
|
15
|
+
Item.class_eval do
|
16
|
+
image_accessor :preview_image
|
17
|
+
video_accessor :trailer_video
|
18
|
+
end
|
19
|
+
Item.dragonfly_apps_for_attributes.should == {:preview_image => app1, :trailer_video => app2}
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should work for included modules (e.g. Mongoid::Document)" do
|
23
|
+
mongoid_document = Module.new
|
24
|
+
app1.define_macro_on_include(mongoid_document, :dog_accessor)
|
25
|
+
model_class = Class.new do
|
26
|
+
def self.before_save(*args); end
|
27
|
+
def self.before_destroy(*args); end
|
28
|
+
include mongoid_document
|
29
|
+
dog_accessor :doogie
|
30
|
+
end
|
31
|
+
model_class.dragonfly_apps_for_attributes.should == {:doogie => app1}
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "correctly defined" do
|
37
|
+
|
38
|
+
before(:each) do
|
39
|
+
@app = Dragonfly[:images]
|
40
|
+
@app.define_macro(model_class, :image_accessor)
|
41
|
+
Item.class_eval do
|
42
|
+
image_accessor :preview_image
|
43
|
+
end
|
44
|
+
@item = Item.new
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should provide a reader" do
|
48
|
+
@item.should respond_to(:preview_image)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should provide a writer" do
|
52
|
+
@item.should respond_to(:preview_image=)
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "when there has been nothing assigned" do
|
56
|
+
it "the reader should return nil" do
|
57
|
+
@item.preview_image.should be_nil
|
58
|
+
end
|
59
|
+
it "the uid should be nil" do
|
60
|
+
@item.preview_image_uid.should be_nil
|
61
|
+
end
|
62
|
+
it "should not try to store anything on save" do
|
63
|
+
@app.datastore.should_not_receive(:store)
|
64
|
+
@item.save!
|
65
|
+
end
|
66
|
+
it "should not try to destroy anything on save" do
|
67
|
+
@app.datastore.should_not_receive(:destroy)
|
68
|
+
@item.save!
|
69
|
+
end
|
70
|
+
it "should not try to destroy anything on destroy" do
|
71
|
+
@app.datastore.should_not_receive(:destroy)
|
72
|
+
@item.destroy
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "when the uid is set manually" do
|
77
|
+
before(:each) do
|
78
|
+
@item.preview_image_uid = 'some_known_uid'
|
79
|
+
end
|
80
|
+
it "should not try to retrieve any data" do
|
81
|
+
@app.datastore.should_not_receive(:retrieve)
|
82
|
+
@item.save!
|
83
|
+
end
|
84
|
+
it "should not try to destroy any data" do
|
85
|
+
@app.datastore.should_not_receive(:destroy)
|
86
|
+
@item.save!
|
87
|
+
end
|
88
|
+
it "should not try to store any data" do
|
89
|
+
@app.datastore.should_not_receive(:store)
|
90
|
+
@item.save!
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "when there has been some thing assigned but not saved" do
|
95
|
+
before(:each) do
|
96
|
+
@item.preview_image = "DATASTRING"
|
97
|
+
end
|
98
|
+
it "the reader should return an attachment" do
|
99
|
+
@item.preview_image.should be_a(Dragonfly::ActiveModelExtensions::Attachment)
|
100
|
+
end
|
101
|
+
it "the uid should be nil" do
|
102
|
+
@item.preview_image_uid.should be_nil
|
103
|
+
end
|
104
|
+
it "should store the image when saved" do
|
105
|
+
@app.datastore.should_receive(:store).with(a_temp_object_with_data("DATASTRING"), {})
|
106
|
+
@item.save!
|
107
|
+
end
|
108
|
+
it "should not try to destroy anything on destroy" do
|
109
|
+
@app.datastore.should_not_receive(:destroy)
|
110
|
+
@item.destroy
|
111
|
+
end
|
112
|
+
it "should return nil for the url" do
|
113
|
+
@item.preview_image.url.should be_nil
|
114
|
+
end
|
115
|
+
describe "when the uid is set manually" do
|
116
|
+
before(:each) do
|
117
|
+
@item.preview_image_uid = 'some_known_uid'
|
118
|
+
end
|
119
|
+
it "should not try to retrieve any data" do
|
120
|
+
@app.datastore.should_not_receive(:retrieve)
|
121
|
+
@item.save!
|
122
|
+
end
|
123
|
+
it "should not try to destroy any data" do
|
124
|
+
@app.datastore.should_not_receive(:destroy)
|
125
|
+
@item.save!
|
126
|
+
end
|
127
|
+
it "should not try to store any data" do
|
128
|
+
@app.datastore.should_not_receive(:store)
|
129
|
+
@item.save!
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "when something has been assigned and saved" do
|
136
|
+
|
137
|
+
before(:each) do
|
138
|
+
@item.preview_image = "DATASTRING"
|
139
|
+
@app.datastore.should_receive(:store).with(a_temp_object_with_data("DATASTRING"), {}).once.and_return('some_uid')
|
140
|
+
@item.save!
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should have the correct uid" do
|
144
|
+
@item.preview_image_uid.should == 'some_uid'
|
145
|
+
end
|
146
|
+
it "should not try to store anything if saved again" do
|
147
|
+
@app.datastore.should_not_receive(:store)
|
148
|
+
@item.save!
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should not try to destroy anything if saved again" do
|
152
|
+
@app.datastore.should_not_receive(:destroy)
|
153
|
+
@item.save!
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should destroy the data on destroy" do
|
157
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
158
|
+
@item.destroy
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should return the url for the data" do
|
162
|
+
@app.should_receive(:url_for).with(an_instance_of(Dragonfly::Job)).and_return('some.url')
|
163
|
+
@item.preview_image.url.should == 'some.url'
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should destroy the old data when the uid is set manually" do
|
167
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
168
|
+
@item.preview_image_uid = 'some_known_uid'
|
169
|
+
@item.save!
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "when accessed by a new model object" do
|
173
|
+
before(:each) do
|
174
|
+
@item = Item.find(@item.id)
|
175
|
+
end
|
176
|
+
it "should destroy the data on destroy" do
|
177
|
+
@app.datastore.should_receive(:destroy).with(@item.preview_image_uid)
|
178
|
+
@item.destroy
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "when something new is assigned" do
|
183
|
+
before(:each) do
|
184
|
+
@item.preview_image = "ANEWDATASTRING"
|
185
|
+
@app.datastore.stub!(:store).and_return('some_uid')
|
186
|
+
end
|
187
|
+
it "should set the uid to nil" do
|
188
|
+
@item.preview_image_uid.should be_nil
|
189
|
+
end
|
190
|
+
it "should destroy the old data when saved" do
|
191
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
192
|
+
@item.save!
|
193
|
+
end
|
194
|
+
it "should not try to destroy the old data if saved again" do
|
195
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
196
|
+
@item.save!
|
197
|
+
@app.datastore.should_not_receive(:destroy).with('some_uid')
|
198
|
+
@item.save!
|
199
|
+
end
|
200
|
+
it "should destroy the old data when saved, even if yet another thing is assigned" do
|
201
|
+
@item.preview_image = "YET ANOTHER DATA STRING"
|
202
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
203
|
+
@item.save!
|
204
|
+
end
|
205
|
+
it "should store the new data when saved" do
|
206
|
+
@app.datastore.should_receive(:store).with(a_temp_object_with_data("ANEWDATASTRING"), {})
|
207
|
+
@item.save!
|
208
|
+
end
|
209
|
+
it "should destroy the old data on destroy" do
|
210
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
211
|
+
@item.destroy
|
212
|
+
end
|
213
|
+
it "should destroy the old data on destroy, even if yet another thing is assigned" do
|
214
|
+
@item.preview_image = "YET ANOTHER DATA STRING"
|
215
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
216
|
+
@item.destroy
|
217
|
+
end
|
218
|
+
it "should destroy the old data when the uid has been set manually" do
|
219
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
220
|
+
@item.preview_image_uid = 'some_known_uid'
|
221
|
+
@item.save!
|
222
|
+
end
|
223
|
+
it "should return the new size" do
|
224
|
+
@item.preview_image.size.should == 14
|
225
|
+
end
|
226
|
+
it "should return the new data" do
|
227
|
+
@item.preview_image.data.should == 'ANEWDATASTRING'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "when it is set to nil" do
|
232
|
+
before(:each) do
|
233
|
+
@item.preview_image = nil
|
234
|
+
end
|
235
|
+
it "should set the uid to nil" do
|
236
|
+
@item.preview_image_uid.should be_nil
|
237
|
+
end
|
238
|
+
it "should return the attribute as nil" do
|
239
|
+
@item.preview_image.should be_nil
|
240
|
+
end
|
241
|
+
it "should destroy the data on save" do
|
242
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
243
|
+
@item.save!
|
244
|
+
@item.preview_image.should be_nil
|
245
|
+
end
|
246
|
+
it "should destroy the old data on destroy" do
|
247
|
+
@app.datastore.should_receive(:destroy).with('some_uid')
|
248
|
+
@item.destroy
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe "when the data can't be found" do
|
253
|
+
it "should log a warning if the data wasn't found on destroy" do
|
254
|
+
@app.datastore.should_receive(:destroy).with('some_uid').and_raise(Dragonfly::DataStorage::DataNotFound)
|
255
|
+
@app.log.should_receive(:warn)
|
256
|
+
@item.destroy
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "other types of assignment" do
|
263
|
+
before(:each) do
|
264
|
+
@app.generator.add :egg do
|
265
|
+
"Gungedin"
|
266
|
+
end
|
267
|
+
@app.processor.add :doogie do |temp_object|
|
268
|
+
temp_object.data.upcase
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
describe "assigning with a job" do
|
273
|
+
before(:each) do
|
274
|
+
@job = @app.generate(:egg)
|
275
|
+
@item.preview_image = @job
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should work" do
|
279
|
+
@item.preview_image.data.should == 'Gungedin'
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should not be affected by subsequent changes to the job" do
|
283
|
+
@job.process!(:doogie)
|
284
|
+
@item.preview_image.data.should == 'Gungedin'
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
describe "assigning with another attachment" do
|
289
|
+
before(:each) do
|
290
|
+
Item.class_eval do
|
291
|
+
image_accessor :other_image
|
292
|
+
end
|
293
|
+
end
|
294
|
+
it "should work like assigning the job" do
|
295
|
+
@item.preview_image = 'eggheads'
|
296
|
+
@item.other_image = @item.preview_image
|
297
|
+
@item.preview_image = 'dogchin'
|
298
|
+
@item.other_image.data.should == 'eggheads'
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe "assigning by means of a bang method" do
|
303
|
+
before(:each) do
|
304
|
+
@app.processor.add :double do |temp_object|
|
305
|
+
temp_object.data * 2
|
306
|
+
end
|
307
|
+
@app.encoder.add do |temp_object, format|
|
308
|
+
temp_object.data.downcase + format.to_s
|
309
|
+
end
|
310
|
+
@item.preview_image = "HELLO"
|
311
|
+
end
|
312
|
+
it "should modify as if being assigned again" do
|
313
|
+
@item.preview_image.process!(:double)
|
314
|
+
@item.preview_image.data.should == 'HELLOHELLO'
|
315
|
+
end
|
316
|
+
it "should update the magic attributes" do
|
317
|
+
@item.preview_image.process!(:double)
|
318
|
+
@item.preview_image_size.should == 10
|
319
|
+
end
|
320
|
+
it "should work for encode" do
|
321
|
+
@item.preview_image.encode!(:egg)
|
322
|
+
@item.preview_image.data.should == 'helloegg'
|
323
|
+
end
|
324
|
+
it "should work repeatedly" do
|
325
|
+
@item.preview_image.process!(:double).encode!(:egg)
|
326
|
+
@item.preview_image.data.should == 'hellohelloegg'
|
327
|
+
@item.preview_image_size.should == 13
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
describe "validations" do
|
335
|
+
|
336
|
+
before(:all) do
|
337
|
+
@app = Dragonfly[:images]
|
338
|
+
@app.define_macro(model_class, :image_accessor)
|
339
|
+
end
|
340
|
+
|
341
|
+
describe "validates_presence_of" do
|
342
|
+
|
343
|
+
before(:all) do
|
344
|
+
Item.class_eval do
|
345
|
+
image_accessor :preview_image
|
346
|
+
validates_presence_of :preview_image
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should be valid if set" do
|
351
|
+
Item.new(:preview_image => "1234567890").should be_valid
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should be invalid if not set" do
|
355
|
+
Item.new.should_not be_valid
|
356
|
+
end
|
357
|
+
|
358
|
+
end
|
359
|
+
|
360
|
+
describe "validates_size_of" do
|
361
|
+
|
362
|
+
before(:all) do
|
363
|
+
Item.class_eval do
|
364
|
+
image_accessor :preview_image
|
365
|
+
validates_size_of :preview_image, :within => (6..10)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
it "should be valid if ok" do
|
370
|
+
Item.new(:preview_image => "1234567890").should be_valid
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should be invalid if too small" do
|
374
|
+
Item.new(:preview_image => "12345").should_not be_valid
|
375
|
+
end
|
376
|
+
|
377
|
+
end
|
378
|
+
|
379
|
+
describe "validates_property" do
|
380
|
+
|
381
|
+
before(:each) do
|
382
|
+
@item = Item.new(:preview_image => "1234567890")
|
383
|
+
end
|
384
|
+
|
385
|
+
before(:all) do
|
386
|
+
custom_analyser = Class.new do
|
387
|
+
def mime_type(temp_object)
|
388
|
+
case temp_object.data
|
389
|
+
when "WRONG TYPE" then 'wrong/type'
|
390
|
+
when "OTHER TYPE" then nil
|
391
|
+
else 'how/special'
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def number_of_Gs(temp_object)
|
396
|
+
temp_object.data.count('G')
|
397
|
+
end
|
398
|
+
end
|
399
|
+
@app.analyser.register(custom_analyser)
|
400
|
+
|
401
|
+
Item.class_eval do
|
402
|
+
validates_property :mime_type, :of => :preview_image, :in => ['how/special', 'how/crazy'], :if => :its_friday
|
403
|
+
validates_property :mime_type, :of => [:other_image, :yet_another_image], :as => 'how/special'
|
404
|
+
validates_property :number_of_Gs, :of => :preview_image, :in => (0..2)
|
405
|
+
validates_property :mime_type, :of => :otra_imagen, :in => ['que/pasa', 'illo/tio'], :message => "tipo de contenido incorrecto. Que chungo tio"
|
406
|
+
|
407
|
+
image_accessor :preview_image
|
408
|
+
image_accessor :other_image
|
409
|
+
image_accessor :yet_another_image
|
410
|
+
image_accessor :otra_imagen
|
411
|
+
|
412
|
+
def its_friday
|
413
|
+
true
|
414
|
+
end
|
415
|
+
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
it "should be valid if nil, if not validated on presence (even with validates_property)" do
|
420
|
+
@item.other_image = nil
|
421
|
+
@item.should be_valid
|
422
|
+
end
|
423
|
+
|
424
|
+
it "should be invalid if the property is nil" do
|
425
|
+
@item.preview_image = "OTHER TYPE"
|
426
|
+
@item.should_not be_valid
|
427
|
+
@item.errors[:preview_image].should match_ar_error("mime type is incorrect. It needs to be one of 'how/special', 'how/crazy', but was ''")
|
428
|
+
end
|
429
|
+
|
430
|
+
it "should be invalid if the property is wrong" do
|
431
|
+
@item.preview_image = "WRONG TYPE"
|
432
|
+
@item.should_not be_valid
|
433
|
+
@item.errors[:preview_image].should match_ar_error("mime type is incorrect. It needs to be one of 'how/special', 'how/crazy', but was 'wrong/type'")
|
434
|
+
end
|
435
|
+
|
436
|
+
it "should work for a range" do
|
437
|
+
@item.preview_image = "GOOGLE GUM"
|
438
|
+
@item.should_not be_valid
|
439
|
+
@item.errors[:preview_image].should match_ar_error("number of gs is incorrect. It needs to be between 0 and 2, but was '3'")
|
440
|
+
end
|
441
|
+
|
442
|
+
it "should validate individually" do
|
443
|
+
@item.other_image = "1234567"
|
444
|
+
@item.yet_another_image = "WRONG TYPE"
|
445
|
+
@item.should_not be_valid
|
446
|
+
@item.errors[:other_image].should match_ar_error(nil)
|
447
|
+
@item.errors[:yet_another_image].should match_ar_error("mime type is incorrect. It needs to be 'how/special', but was 'wrong/type'")
|
448
|
+
end
|
449
|
+
|
450
|
+
it "should include standard extra options like 'if' on mime type validation" do
|
451
|
+
@item.should_receive(:its_friday).and_return(false)
|
452
|
+
@item.preview_image = "WRONG TYPE"
|
453
|
+
@item.should be_valid
|
454
|
+
end
|
455
|
+
|
456
|
+
it "should require either :as or :in as an argument" do
|
457
|
+
lambda{
|
458
|
+
Item.class_eval do
|
459
|
+
validates_property :mime_type, :of => :preview_image
|
460
|
+
end
|
461
|
+
}.should raise_error(ArgumentError)
|
462
|
+
end
|
463
|
+
|
464
|
+
it "should require :of as an argument" do
|
465
|
+
lambda{
|
466
|
+
Item.class_eval do
|
467
|
+
validates_property :mime_type, :as => 'hi/there'
|
468
|
+
end
|
469
|
+
}.should raise_error(ArgumentError)
|
470
|
+
end
|
471
|
+
|
472
|
+
it "should allow for custom messages" do
|
473
|
+
@item.otra_imagen = "WRONG TYPE"
|
474
|
+
@item.should_not be_valid
|
475
|
+
@item.errors[:otra_imagen].should match_ar_error("tipo de contenido incorrecto. Que chungo tio")
|
476
|
+
end
|
477
|
+
|
478
|
+
end
|
479
|
+
|
480
|
+
end
|
481
|
+
|
482
|
+
describe "extra properties" do
|
483
|
+
|
484
|
+
before(:each) do
|
485
|
+
@app = Dragonfly[:images]
|
486
|
+
custom_analyser = Class.new do
|
487
|
+
def some_analyser_method(temp_object)
|
488
|
+
"abc" + temp_object.data[0..0]
|
489
|
+
end
|
490
|
+
def number_of_As(temp_object); temp_object.data.count('A'); end
|
491
|
+
end
|
492
|
+
@app.analyser.register(custom_analyser)
|
493
|
+
@app.define_macro(model_class, :image_accessor)
|
494
|
+
Item.class_eval do
|
495
|
+
image_accessor :preview_image
|
496
|
+
end
|
497
|
+
@item = Item.new
|
498
|
+
end
|
499
|
+
|
500
|
+
describe "magic attributes" do
|
501
|
+
|
502
|
+
it "should default the magic attribute as nil" do
|
503
|
+
@item.preview_image_some_analyser_method.should be_nil
|
504
|
+
end
|
505
|
+
|
506
|
+
it "should set the magic attribute when assigned" do
|
507
|
+
@item.preview_image = '123'
|
508
|
+
@item.preview_image_some_analyser_method.should == 'abc1'
|
509
|
+
end
|
510
|
+
|
511
|
+
it "should not set non-magic attributes with the same prefix when assigned" do
|
512
|
+
@item.preview_image_blah_blah = 'wassup'
|
513
|
+
@item.preview_image = '123'
|
514
|
+
@item.preview_image_blah_blah.should == 'wassup'
|
515
|
+
end
|
516
|
+
|
517
|
+
it "should update the magic attribute when something else is assigned" do
|
518
|
+
@item.preview_image = '123'
|
519
|
+
@item.preview_image = '456'
|
520
|
+
@item.preview_image_some_analyser_method.should == 'abc4'
|
521
|
+
end
|
522
|
+
|
523
|
+
it "should reset the magic attribute when set to nil" do
|
524
|
+
@item.preview_image = '123'
|
525
|
+
@item.preview_image = nil
|
526
|
+
@item.preview_image_some_analyser_method.should be_nil
|
527
|
+
end
|
528
|
+
|
529
|
+
it "should not reset non-magic attributes with the same prefix when set to nil" do
|
530
|
+
@item.preview_image_blah_blah = 'wassup'
|
531
|
+
@item.preview_image = '123'
|
532
|
+
@item.preview_image = nil
|
533
|
+
@item.preview_image_blah_blah.should == 'wassup'
|
534
|
+
end
|
535
|
+
|
536
|
+
it "should work for size too" do
|
537
|
+
@item.preview_image = '123'
|
538
|
+
@item.preview_image_size.should == 3
|
539
|
+
end
|
540
|
+
|
541
|
+
it "should store the original file extension if it exists" do
|
542
|
+
data = 'jasdlkf sadjl'
|
543
|
+
data.stub!(:original_filename).and_return('hello.png')
|
544
|
+
@item.preview_image = data
|
545
|
+
@item.preview_image_ext.should == 'png'
|
546
|
+
end
|
547
|
+
|
548
|
+
it "should store the original file name if it exists" do
|
549
|
+
data = 'jasdlkf sadjl'
|
550
|
+
data.stub!(:original_filename).and_return('hello.png')
|
551
|
+
@item.preview_image = data
|
552
|
+
@item.preview_image_name.should == 'hello.png'
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
|
557
|
+
describe "delegating methods to the job" do
|
558
|
+
before(:each) do
|
559
|
+
@item.preview_image = "DATASTRING"
|
560
|
+
end
|
561
|
+
it "should have properties from the analyser" do
|
562
|
+
@item.preview_image.number_of_As.should == 2
|
563
|
+
end
|
564
|
+
it "should report that it responds to analyser methods" do
|
565
|
+
@item.preview_image.respond_to?(:number_of_As).should be_true
|
566
|
+
end
|
567
|
+
it "should include analyser methods in methods" do
|
568
|
+
@item.preview_image.methods.include?('number_of_As'.to_method_name).should be_true
|
569
|
+
end
|
570
|
+
it "should include analyser methods in public_methods" do
|
571
|
+
@item.preview_image.public_methods.include?('number_of_As'.to_method_name).should be_true
|
572
|
+
end
|
573
|
+
|
574
|
+
it "should update when something new is assigned" do
|
575
|
+
@item.preview_image = 'ANEWDATASTRING'
|
576
|
+
@item.preview_image.number_of_As.should == 3
|
577
|
+
end
|
578
|
+
|
579
|
+
describe "from a new model object" do
|
580
|
+
before(:each) do
|
581
|
+
@app.datastore.stub!(:store).and_return('my_uid')
|
582
|
+
item = Item.create!(:preview_image => 'DATASTRING')
|
583
|
+
@item = Item.find(item.id)
|
584
|
+
end
|
585
|
+
it "should load the content then delegate the method" do
|
586
|
+
@app.datastore.should_receive(:retrieve).with('my_uid').and_return(['DATASTRING', {}])
|
587
|
+
@item.preview_image.number_of_As.should == 2
|
588
|
+
end
|
589
|
+
it "should use the magic attribute if there is one, and not load the content" do
|
590
|
+
@app.datastore.should_not_receive(:retrieve)
|
591
|
+
@item.should_receive(:preview_image_some_analyser_method).and_return('result yo')
|
592
|
+
@item.preview_image.some_analyser_method.should == 'result yo'
|
593
|
+
end
|
594
|
+
|
595
|
+
%w(size name ext).each do |attr|
|
596
|
+
it "should use the magic attribute for #{attr} if there is one, and not load the content" do
|
597
|
+
@app.datastore.should_not_receive(:retrieve)
|
598
|
+
@item.should_receive("preview_image_#{attr}".to_sym).and_return('result yo')
|
599
|
+
@item.preview_image.send(attr).should == 'result yo'
|
600
|
+
end
|
601
|
+
|
602
|
+
it "should load the content then delegate '#{attr}' if there is no magic attribute for it" do
|
603
|
+
@item.should_receive(:public_methods).and_return(['preview_image_uid']) # no magic attributes
|
604
|
+
@app.datastore.should_receive(:retrieve).with('my_uid').and_return(['DATASTRING', {}])
|
605
|
+
@item.preview_image.send(attr).should == @item.preview_image.send(:job).send(attr)
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
end
|
610
|
+
|
611
|
+
it "should not raise an error if a non-existent method is called" do
|
612
|
+
# Just checking method missing works ok
|
613
|
+
lambda{
|
614
|
+
@item.preview_image.eggbert
|
615
|
+
}.should raise_error(NoMethodError)
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
describe "setting things on the attachment" do
|
620
|
+
|
621
|
+
before(:each) do
|
622
|
+
@item = Item.new
|
623
|
+
end
|
624
|
+
|
625
|
+
describe "name" do
|
626
|
+
before(:each) do
|
627
|
+
@item.preview_image = "Hello"
|
628
|
+
@item.preview_image.name = 'hello.there'
|
629
|
+
end
|
630
|
+
it "should allow for setting the name" do
|
631
|
+
@item.preview_image.name.should == 'hello.there'
|
632
|
+
end
|
633
|
+
it "should update the magic attribute" do
|
634
|
+
@item.preview_image_name.should == 'hello.there'
|
635
|
+
end
|
636
|
+
it "should return the name" do
|
637
|
+
(@item.preview_image.name = 'no.silly').should == 'no.silly'
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
describe "meta" do
|
642
|
+
before(:each) do
|
643
|
+
@item.preview_image = "Hello all"
|
644
|
+
@item.preview_image.meta = {:slime => 'balls'}
|
645
|
+
end
|
646
|
+
it "should allow for setting the meta" do
|
647
|
+
@item.preview_image.meta.should == {:slime => 'balls'}
|
648
|
+
end
|
649
|
+
it "should allow for updating the meta" do
|
650
|
+
@item.preview_image.meta[:numb] = 'nuts'
|
651
|
+
@item.preview_image.meta.should == {:slime => 'balls', :numb => 'nuts'}
|
652
|
+
end
|
653
|
+
it "should return the meta" do
|
654
|
+
(@item.preview_image.meta = {:doogs => 'boogs'}).should == {:doogs => 'boogs'}
|
655
|
+
end
|
656
|
+
it "should save it correctly" do
|
657
|
+
@item.save!
|
658
|
+
item = Item.find(@item.id)
|
659
|
+
item.preview_image.meta.should include_hash(:slime => 'balls')
|
660
|
+
end
|
661
|
+
it "should store meta info about the model" do
|
662
|
+
@item.save!
|
663
|
+
meta = {:model_class => 'Item', :model_attachment => :preview_image, :slime => 'balls'}
|
664
|
+
@app.fetch(@item.preview_image_uid).meta.should == meta
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
end
|
669
|
+
|
670
|
+
end
|
671
|
+
|
672
|
+
describe "inheritance" do
|
673
|
+
|
674
|
+
before(:all) do
|
675
|
+
@app = Dragonfly[:images]
|
676
|
+
@app2 = Dragonfly[:egg]
|
677
|
+
@app.define_macro(model_class, :image_accessor)
|
678
|
+
@app2.define_macro(model_class, :egg_accessor)
|
679
|
+
Car.class_eval do
|
680
|
+
image_accessor :image
|
681
|
+
end
|
682
|
+
Photo.class_eval do
|
683
|
+
egg_accessor :image
|
684
|
+
end
|
685
|
+
|
686
|
+
@base_class = Car
|
687
|
+
class ReliantRobin < Car; image_accessor :reliant_image; end
|
688
|
+
@subclass = ReliantRobin
|
689
|
+
class ReliantRobinWithModule < Car
|
690
|
+
include Module.new
|
691
|
+
image_accessor :reliant_image
|
692
|
+
end
|
693
|
+
@subclass_with_module = ReliantRobinWithModule
|
694
|
+
@unrelated_class = Photo
|
695
|
+
end
|
696
|
+
|
697
|
+
it "should allow assigning base class accessors" do
|
698
|
+
@base_class.create! :image => 'blah'
|
699
|
+
end
|
700
|
+
it "should not allow assigning subclass accessors in the base class" do
|
701
|
+
@base_class.new.should_not respond_to(:reliant_image=)
|
702
|
+
end
|
703
|
+
it "should allow assigning base class accessors in the subclass" do
|
704
|
+
@subclass.create! :image => 'blah'
|
705
|
+
end
|
706
|
+
it "should allow assigning subclass accessors in the subclass" do
|
707
|
+
@subclass.create! :reliant_image => 'blah'
|
708
|
+
end
|
709
|
+
it "should allow assigning base class accessors in the subclass, even if it has mixins" do
|
710
|
+
@subclass_with_module.create! :image => 'blah'
|
711
|
+
end
|
712
|
+
it "should allow assigning subclass accessors in the subclass, even if it has mixins" do
|
713
|
+
@subclass_with_module.create! :reliant_image => 'blah'
|
714
|
+
end
|
715
|
+
it "return the correct apps for each accessors, even when names clash" do
|
716
|
+
@base_class.dragonfly_apps_for_attributes.should == {:image => @app}
|
717
|
+
@subclass.dragonfly_apps_for_attributes.should == {:image => @app, :reliant_image => @app}
|
718
|
+
@subclass_with_module.dragonfly_apps_for_attributes.should == {:image => @app, :reliant_image => @app}
|
719
|
+
@unrelated_class.dragonfly_apps_for_attributes.should == {:image => @app2}
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
end
|