dragonfly 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dragonfly might be problematic. Click here for more details.

Files changed (157) hide show
  1. data/.gitignore +2 -0
  2. data/.specopts +2 -0
  3. data/.yardopts +11 -5
  4. data/Gemfile +22 -0
  5. data/Gemfile.rails.2.3.5 +13 -0
  6. data/History.md +49 -0
  7. data/README.md +18 -28
  8. data/Rakefile +24 -36
  9. data/VERSION +1 -1
  10. data/config.ru +4 -1
  11. data/dragonfly.gemspec +85 -99
  12. data/extra_docs/Analysers.md +66 -30
  13. data/extra_docs/Caching.md +22 -0
  14. data/extra_docs/Configuration.md +116 -0
  15. data/extra_docs/DataStorage.md +114 -14
  16. data/extra_docs/Encoding.md +62 -37
  17. data/extra_docs/GeneralUsage.md +118 -0
  18. data/extra_docs/Generators.md +92 -0
  19. data/extra_docs/Heroku.md +51 -0
  20. data/extra_docs/Index.md +8 -9
  21. data/extra_docs/MimeTypes.md +18 -17
  22. data/extra_docs/Models.md +251 -0
  23. data/extra_docs/Processing.md +94 -70
  24. data/extra_docs/Rack.md +53 -0
  25. data/extra_docs/Rails2.md +44 -0
  26. data/extra_docs/Rails3.md +51 -0
  27. data/extra_docs/Sinatra.md +21 -0
  28. data/extra_docs/URLs.md +114 -0
  29. data/features/images.feature +6 -7
  30. data/features/no_processing.feature +0 -6
  31. data/features/rails_2.3.5.feature +1 -1
  32. data/features/rails_3.0.0.rc.feature +8 -0
  33. data/features/steps/dragonfly_steps.rb +14 -12
  34. data/features/steps/rails_steps.rb +20 -9
  35. data/features/support/env.rb +10 -11
  36. data/fixtures/files/app/views/albums/new.html.erb +4 -4
  37. data/fixtures/files/app/views/albums/show.html.erb +1 -1
  38. data/fixtures/files/features/manage_album_images.feature +1 -1
  39. data/fixtures/files/features/step_definitions/{album_steps.rb → image_steps.rb} +4 -3
  40. data/fixtures/files/features/support/paths.rb +2 -0
  41. data/fixtures/files/features/text_images.feature +7 -0
  42. data/fixtures/rails_3.0.0.rc/template.rb +21 -0
  43. data/irbrc.rb +2 -1
  44. data/lib/dragonfly.rb +4 -16
  45. data/lib/dragonfly/{active_record_extensions.rb → active_model_extensions.rb} +1 -1
  46. data/lib/dragonfly/active_model_extensions/attachment.rb +146 -0
  47. data/lib/dragonfly/{active_record_extensions → active_model_extensions}/class_methods.rb +5 -6
  48. data/lib/dragonfly/{active_record_extensions → active_model_extensions}/instance_methods.rb +1 -1
  49. data/lib/dragonfly/{active_record_extensions → active_model_extensions}/validations.rb +5 -9
  50. data/lib/dragonfly/analyser.rb +59 -0
  51. data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
  52. data/lib/dragonfly/analysis/r_magick_analyser.rb +46 -31
  53. data/lib/dragonfly/app.rb +138 -173
  54. data/lib/dragonfly/config/heroku.rb +19 -0
  55. data/lib/dragonfly/config/r_magick.rb +37 -0
  56. data/lib/dragonfly/config/{rails_defaults.rb → rails.rb} +6 -7
  57. data/lib/dragonfly/configurable.rb +30 -27
  58. data/lib/dragonfly/core_ext/object.rb +1 -1
  59. data/lib/dragonfly/data_storage/file_data_store.rb +59 -26
  60. data/lib/dragonfly/data_storage/mongo_data_store.rb +65 -0
  61. data/lib/dragonfly/data_storage/s3data_store.rb +31 -12
  62. data/lib/dragonfly/encoder.rb +13 -0
  63. data/lib/dragonfly/encoding/r_magick_encoder.rb +10 -19
  64. data/lib/dragonfly/endpoint.rb +43 -0
  65. data/lib/dragonfly/function_manager.rb +65 -0
  66. data/lib/dragonfly/{processing/r_magick_text_processor.rb → generation/r_magick_generator.rb} +25 -11
  67. data/lib/dragonfly/generator.rb +9 -0
  68. data/lib/dragonfly/job.rb +290 -0
  69. data/lib/dragonfly/job_builder.rb +39 -0
  70. data/lib/dragonfly/job_definitions.rb +26 -0
  71. data/lib/dragonfly/job_endpoint.rb +17 -0
  72. data/lib/dragonfly/loggable.rb +28 -0
  73. data/lib/dragonfly/middleware.rb +21 -14
  74. data/lib/dragonfly/processing/r_magick_processor.rb +71 -48
  75. data/lib/dragonfly/processor.rb +9 -0
  76. data/lib/dragonfly/r_magick_utils.rb +24 -0
  77. data/lib/dragonfly/rails/images.rb +10 -7
  78. data/lib/dragonfly/routed_endpoint.rb +42 -0
  79. data/lib/dragonfly/serializer.rb +32 -0
  80. data/lib/dragonfly/simple_cache.rb +23 -0
  81. data/lib/dragonfly/simple_endpoint.rb +64 -0
  82. data/lib/dragonfly/temp_object.rb +77 -45
  83. data/spec/argument_matchers.rb +7 -17
  84. data/spec/dragonfly/active_model_extensions/active_model_setup.rb +97 -0
  85. data/spec/dragonfly/active_model_extensions/active_record_setup.rb +85 -0
  86. data/spec/dragonfly/{active_record_extensions → active_model_extensions}/model_spec.rb +282 -244
  87. data/spec/dragonfly/active_model_extensions/spec_helper.rb +11 -0
  88. data/spec/dragonfly/analyser_spec.rb +123 -0
  89. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +2 -2
  90. data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +10 -1
  91. data/spec/dragonfly/app_spec.rb +175 -69
  92. data/spec/dragonfly/configurable_spec.rb +14 -0
  93. data/spec/dragonfly/data_storage/data_store_spec.rb +36 -9
  94. data/spec/dragonfly/data_storage/file_data_store_spec.rb +61 -38
  95. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +18 -0
  96. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +34 -39
  97. data/spec/dragonfly/deprecation_spec.rb +20 -0
  98. data/spec/dragonfly/function_manager_spec.rb +154 -0
  99. data/spec/dragonfly/generation/r_magick_generator_spec.rb +119 -0
  100. data/spec/dragonfly/job_builder_spec.rb +37 -0
  101. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  102. data/spec/dragonfly/job_endpoint_spec.rb +66 -0
  103. data/spec/dragonfly/job_spec.rb +605 -0
  104. data/spec/dragonfly/loggable_spec.rb +80 -0
  105. data/spec/dragonfly/middleware_spec.rb +37 -17
  106. data/spec/dragonfly/processing/r_magick_processor_spec.rb +182 -166
  107. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  108. data/spec/dragonfly/serializer_spec.rb +61 -0
  109. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  110. data/spec/dragonfly/simple_endpoint_spec.rb +78 -0
  111. data/spec/dragonfly/temp_object_spec.rb +154 -119
  112. data/spec/simple_matchers.rb +22 -0
  113. data/spec/spec_helper.rb +28 -4
  114. data/yard/templates/default/layout/html/layout.erb +18 -11
  115. metadata +89 -190
  116. data/config.rb +0 -5
  117. data/extra_docs/ActiveRecord.md +0 -196
  118. data/extra_docs/ExampleUseCases.md +0 -189
  119. data/extra_docs/GettingStarted.md +0 -114
  120. data/extra_docs/Shortcuts.md +0 -118
  121. data/extra_docs/UsingWithRails.md +0 -81
  122. data/features/rails_3.0.0.beta3.feature +0 -7
  123. data/fixtures/rails_3.0.0.beta3/template.rb +0 -16
  124. data/lib/dragonfly/active_record_extensions/attachment.rb +0 -170
  125. data/lib/dragonfly/analyser_list.rb +0 -9
  126. data/lib/dragonfly/analysis/base.rb +0 -10
  127. data/lib/dragonfly/belongs_to_app.rb +0 -24
  128. data/lib/dragonfly/config/heroku_rails_images.rb +0 -23
  129. data/lib/dragonfly/config/r_magick_images.rb +0 -69
  130. data/lib/dragonfly/config/r_magick_text.rb +0 -25
  131. data/lib/dragonfly/config/rails_images.rb +0 -13
  132. data/lib/dragonfly/data_storage/base.rb +0 -21
  133. data/lib/dragonfly/data_storage/base64_data_store.rb +0 -23
  134. data/lib/dragonfly/data_storage/transparent_data_store.rb +0 -21
  135. data/lib/dragonfly/delegatable.rb +0 -14
  136. data/lib/dragonfly/delegator.rb +0 -62
  137. data/lib/dragonfly/encoder_list.rb +0 -9
  138. data/lib/dragonfly/encoding/base.rb +0 -14
  139. data/lib/dragonfly/encoding/transparent_encoder.rb +0 -14
  140. data/lib/dragonfly/extended_temp_object.rb +0 -120
  141. data/lib/dragonfly/parameters.rb +0 -163
  142. data/lib/dragonfly/processing/base.rb +0 -10
  143. data/lib/dragonfly/processor_list.rb +0 -9
  144. data/lib/dragonfly/url_handler.rb +0 -147
  145. data/spec/dragonfly/active_record_extensions/attachment_spec.rb +0 -8
  146. data/spec/dragonfly/active_record_extensions/migration.rb +0 -42
  147. data/spec/dragonfly/active_record_extensions/models.rb +0 -6
  148. data/spec/dragonfly/active_record_extensions/spec_helper.rb +0 -24
  149. data/spec/dragonfly/belongs_to_app_spec.rb +0 -55
  150. data/spec/dragonfly/delegatable_spec.rb +0 -32
  151. data/spec/dragonfly/delegator_spec.rb +0 -145
  152. data/spec/dragonfly/extended_temp_object_spec.rb +0 -71
  153. data/spec/dragonfly/parameters_spec.rb +0 -298
  154. data/spec/dragonfly/processing/r_magick_text_processor_spec.rb +0 -84
  155. data/spec/dragonfly/url_handler_spec.rb +0 -247
  156. data/spec/dragonfly_spec.rb +0 -16
  157. data/spec/ginger_scenarios.rb +0 -13
@@ -0,0 +1,23 @@
1
+ module Dragonfly
2
+ class SimpleCache < Hash
3
+
4
+ def initialize(max_size)
5
+ @max_size = max_size
6
+ @keys = []
7
+ end
8
+
9
+ attr_reader :max_size
10
+
11
+ def []=(key, value)
12
+ if !has_key?(key)
13
+ @keys << key
14
+ if size == max_size
15
+ key_to_purge = @keys.shift
16
+ delete(key_to_purge)
17
+ end
18
+ end
19
+ super
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,64 @@
1
+ module Dragonfly
2
+ class SimpleEndpoint
3
+
4
+ include Endpoint
5
+ include Loggable
6
+
7
+ # Instance methods
8
+
9
+ def initialize(app)
10
+ @app = app
11
+ use_same_log_as(app)
12
+ end
13
+
14
+ def call(env)
15
+ request = Rack::Request.new(env)
16
+
17
+ case request.path_info
18
+ when '', '/', app.url_path_prefix
19
+ dragonfly_response
20
+ else
21
+ job = Job.from_path(request.path_info, app)
22
+ job.validate_sha!(request['s']) if app.protect_from_dos_attacks
23
+ response_for_job(job, env)
24
+ end
25
+ rescue Serializer::BadString, Job::InvalidArray => e
26
+ log.warn(e.message)
27
+ [404, {'Content-Type' => 'text/plain'}, ['Not found']]
28
+ rescue Job::NoSHAGiven => e
29
+ [400, {"Content-Type" => 'text/plain'}, ["You need to give a SHA parameter"]]
30
+ rescue Job::IncorrectSHA => e
31
+ [400, {"Content-Type" => 'text/plain'}, ["The SHA parameter you gave (#{e}) is incorrect"]]
32
+ end
33
+
34
+ def required_params_for(job)
35
+ {'s' => job.sha}
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :app
41
+
42
+ def dragonfly_response
43
+ body = <<-DRAGONFLY
44
+ _o|o_
45
+ _~~---._( )_.---~~_
46
+ ( . \\ / . )
47
+ `-.~--' |=| '--~.-'
48
+ _~-.~'" /|=|\\ "'~.-~_
49
+ ( ./ |=| \\. )
50
+ `~~`"` |=| `"'~~"
51
+ |-|
52
+ <->
53
+ V
54
+ DRAGONFLY
55
+ [200, {
56
+ 'Content-Type' => 'text/plain',
57
+ 'Content-Size' => body.bytesize.to_s
58
+ },
59
+ [body]
60
+ ]
61
+ end
62
+
63
+ end
64
+ end
@@ -29,41 +29,36 @@ module Dragonfly
29
29
  # are ever called, then the filesystem will never be hit.
30
30
  #
31
31
  class TempObject
32
-
32
+
33
33
  # Class configuration
34
34
  class << self
35
-
35
+
36
36
  include Configurable
37
37
  configurable_attr :block_size, 8192
38
-
38
+
39
39
  end
40
-
40
+
41
41
  # Instance Methods
42
-
43
- def initialize(obj)
42
+
43
+ def initialize(obj, opts={})
44
44
  initialize_from_object!(obj)
45
+ validate_options!(opts)
46
+ extract_attributes_from(opts)
45
47
  end
46
-
47
- def modify_self!(obj)
48
- unless obj == self
49
- reset!
50
- initialize_from_object!(obj)
51
- end
52
- self
53
- end
54
-
48
+
55
49
  def data
56
50
  @data ||= initialized_data || file.read
57
51
  end
58
52
 
59
53
  def tempfile
60
54
  @tempfile ||= begin
61
- if initialized_tempfile
55
+ case initialized_with
56
+ when :tempfile
62
57
  @tempfile = initialized_tempfile
63
- elsif initialized_data
58
+ when :data
64
59
  @tempfile = Tempfile.new('dragonfly')
65
60
  @tempfile.write(initialized_data)
66
- elsif initialized_file
61
+ when :file
67
62
  @tempfile = copy_to_tempfile(initialized_file.path)
68
63
  end
69
64
  @tempfile.close
@@ -81,11 +76,11 @@ module Dragonfly
81
76
  end
82
77
  ret
83
78
  end
84
-
79
+
85
80
  def path
86
81
  tempfile.path
87
82
  end
88
-
83
+
89
84
  def size
90
85
  if initialized_data
91
86
  initialized_data.bytesize
@@ -93,24 +88,22 @@ module Dragonfly
93
88
  File.size(path)
94
89
  end
95
90
  end
96
-
97
- attr_writer :name
98
-
99
- def name
100
- @name unless @name.blank?
91
+
92
+ attr_reader :name, :format
93
+ alias _format format
94
+
95
+ def meta
96
+ @meta ||= {}
101
97
  end
102
-
98
+
103
99
  def basename
104
- return unless name
105
- name.sub(/\.[^.]+$/,'')
100
+ File.basename(name, '.*') if name
106
101
  end
107
-
102
+
108
103
  def ext
109
- return unless name
110
- bits = name.split('.')
111
- bits.last if bits.size > 1
104
+ File.extname(name)[/\.(.*)/, 1] if name
112
105
  end
113
-
106
+
114
107
  def each(&block)
115
108
  to_io do |io|
116
109
  while part = io.read(block_size)
@@ -118,7 +111,7 @@ module Dragonfly
118
111
  end
119
112
  end
120
113
  end
121
-
114
+
122
115
  def to_file(path)
123
116
  if initialized_data
124
117
  File.open(path, 'w'){|f| f.write(initialized_data) }
@@ -127,7 +120,7 @@ module Dragonfly
127
120
  end
128
121
  File.new(path)
129
122
  end
130
-
123
+
131
124
  def to_io(&block)
132
125
  if initialized_data
133
126
  StringIO.open(initialized_data, &block)
@@ -136,16 +129,39 @@ module Dragonfly
136
129
  end
137
130
  end
138
131
 
132
+ def attributes
133
+ {
134
+ :name => name,
135
+ :meta => meta,
136
+ :format => format
137
+ }
138
+ end
139
+
140
+ def extract_attributes_from(hash)
141
+ self.name = hash.delete(:name) unless hash[:name].blank?
142
+ self.meta = hash.delete(:meta) unless hash[:meta].blank?
143
+ self.format = hash.delete(:format) unless hash[:format].blank?
144
+ end
145
+
146
+ def inspect
147
+ content_string = case initialized_with
148
+ when :data
149
+ data_string = size > 20 ? "#{initialized_data[0..20]}..." : initialized_data
150
+ "data=#{data_string.inspect}"
151
+ when :file then "file=#{initialized_file.inspect}"
152
+ when :tempfile then "tempfile=#{initialized_tempfile.inspect}"
153
+ end
154
+ to_s.sub(/>$/, " #{content_string}, @meta=#{@meta.inspect}, @name=#{@name.inspect} >")
155
+ end
156
+
139
157
  protected
140
-
158
+
141
159
  attr_accessor :initialized_data, :initialized_tempfile, :initialized_file
142
-
160
+
143
161
  private
144
-
145
- def reset!
146
- @data = @tempfile = @initialized_data = @initialized_file = @initialized_tempfile = nil
147
- end
148
-
162
+
163
+ attr_writer :name, :meta, :format
164
+
149
165
  def initialize_from_object!(obj)
150
166
  case obj
151
167
  when TempObject
@@ -164,16 +180,32 @@ module Dragonfly
164
180
  end
165
181
  self.name = obj.original_filename if obj.respond_to?(:original_filename)
166
182
  end
167
-
183
+
184
+ def initialized_with
185
+ if initialized_tempfile
186
+ :tempfile
187
+ elsif initialized_data
188
+ :data
189
+ elsif initialized_file
190
+ :file
191
+ end
192
+ end
193
+
168
194
  def block_size
169
195
  self.class.block_size
170
196
  end
171
-
197
+
172
198
  def copy_to_tempfile(path)
173
199
  tempfile = Tempfile.new('dragonfly')
174
200
  FileUtils.cp File.expand_path(path), tempfile.path
175
201
  tempfile
176
202
  end
177
-
203
+
204
+ def validate_options!(opts)
205
+ valid_keys = [:name, :meta, :format]
206
+ invalid_keys = opts.keys - valid_keys
207
+ raise ArgumentError, "Unrecognised options #{invalid_keys.inspect}" if invalid_keys.any?
208
+ end
209
+
178
210
  end
179
211
  end
@@ -3,27 +3,17 @@ def string_matching(regexp)
3
3
  end
4
4
 
5
5
  class TempObjectArgumentMatcher
6
- def initialize(data)
6
+ def initialize(data, opts)
7
7
  @data = data
8
+ @opts = opts
8
9
  end
9
10
  def ==(actual)
10
- actual.is_a?(Dragonfly::TempObject) && actual.data == @data
11
+ actual.is_a?(Dragonfly::TempObject) &&
12
+ actual.data == @data &&
13
+ @opts.all?{|k,v| actual.send(k) == v }
11
14
  end
12
15
  end
13
16
 
14
- def a_temp_object_with_data(data)
15
- TempObjectArgumentMatcher.new(data)
16
- end
17
-
18
- class ParametersArgumentMatcher
19
- def initialize(hash)
20
- @hash = hash
21
- end
22
- def ==(actual)
23
- actual.to_hash.reject{|k,v| v.nil? || v.respond_to?(:empty?) && v.empty?} == @hash
24
- end
25
- end
26
-
27
- def parameters_matching(hash)
28
- ParametersArgumentMatcher.new(hash)
17
+ def a_temp_object_with_data(data, opts={})
18
+ TempObjectArgumentMatcher.new(data, opts)
29
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