carrierwave-base64 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d46d2f9f96d23a40a168aa3a25f1d79475cac873e7b1e004153199aa12c11962
4
- data.tar.gz: 77d81babfb99831edae4fc362010c13639a957b0ff56377420744f56de5eb029
3
+ metadata.gz: c9da0e56ae6151c3068b895309bd70f9bfba959b28785b8fafde064bfecc9047
4
+ data.tar.gz: b723fcc95905b624fdc54394129bd9629b8bc1aa781061fc992f6f2ec3405d6f
5
5
  SHA512:
6
- metadata.gz: 8707ca4f1b52279e6c1f6a8eec3b576029fd1fd4641ecdf656e824afd697d7e04d94e54e9fc796df648f8626711d3f2a53cb3758f5cd04d8305f1bc20696114b
7
- data.tar.gz: 856803d525d0d2b614ae21688e424de5c9f98ecad8dd1d39feb9509bed63d7f2fa3b68a80377bd0fbdb790f1f4c39a000bba5629aed6cded3f39fd523862988b
6
+ metadata.gz: ccb2e7e949025a1eb37ba1bea875219ea269b561f6783f44203ba3085f9e2455913f9e01eb540e54165d0f4e5cc371cae4009dc367a2a278d9f65b6d26c01dc0
7
+ data.tar.gz: a429b36e280b49ac842bcf26ccf73c096cce0a3a67129ee97a3c92fd391a38ffb3486220c947a9a243e8d7db7a4997b81cfad9b36d0e3c974ad451d6f1b71286
@@ -4,3 +4,4 @@ Documentation:
4
4
  Metrics/BlockLength:
5
5
  Exclude:
6
6
  - "spec/**/*"
7
+ - "*.gemspec"
@@ -1,16 +1,17 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.1.10
5
4
  - 2.2.10
6
- - 2.3.7
7
- - 2.4.4
8
- - 2.5.1
5
+ - 2.3.8
6
+ - 2.4.5
7
+ - 2.5.2
9
8
  - ruby-head
9
+ - jruby-head
10
10
 
11
11
  matrix:
12
12
  allow_failures:
13
13
  - rvm: ruby-head
14
+ - rvm: jruby-head
14
15
 
15
16
  gemfile:
16
17
  - Gemfile
@@ -1,5 +1,9 @@
1
1
  # carrierwave-base64 changelog
2
2
 
3
+ ## 2.8.0
4
+
5
+ - Mime Type is now detected from file contents, falling back to the type, specified by the user. (#73, @justisb)
6
+
3
7
  ## 2.7.0
4
8
 
5
9
  - Railtie is not required by default, so the gem can be used in non Rails app (@sleepingstu)
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Carrierwave::Base64
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/carrierwave-base64.svg)](http://badge.fury.io/rb/carrierwave-base64)
4
- [![Build Status](https://travis-ci.org/lebedev-yury/carrierwave-base64.svg?branch=master)](https://travis-ci.org/lebedev-yury/carrierwave-base64)
5
- [![Code Climate](https://codeclimate.com/github/lebedev-yury/carrierwave-base64/badges/gpa.svg)](https://codeclimate.com/github/lebedev-yury/carrierwave-base64)
4
+ [![Build Status](https://travis-ci.org/y9v/carrierwave-base64.svg?branch=master)](https://travis-ci.org/y9v/carrierwave-base64)
5
+ [![Code Climate](https://codeclimate.com/github/y9v/carrierwave-base64/badges/gpa.svg)](https://codeclimate.com/github/y9v/carrierwave-base64)
6
+ [![Inch CI](https://inch-ci.org/github/y9v/carrierwave-base64.svg?branch=master)](https://inch-ci.org/github/y9v/carrierwave-base64)
6
7
 
7
8
  Upload files encoded as base64 to carrierwave.
8
9
 
@@ -21,15 +21,17 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency 'carrierwave', '>= 0.8.0'
23
23
  spec.add_dependency 'mime-types', '~> 3.0'
24
+ spec.add_dependency 'mimemagic', '~> 0.3.2'
24
25
 
25
26
  spec.add_development_dependency 'bundler', '~> 1.7'
26
27
  spec.add_development_dependency 'carrierwave-mongoid'
27
28
  spec.add_development_dependency 'mongoid'
28
29
  spec.add_development_dependency 'pry'
29
- spec.add_development_dependency 'rails', '~> 4'
30
+ spec.add_development_dependency 'rails', '~> 5'
30
31
  spec.add_development_dependency 'rake', '~> 10.0'
31
32
  spec.add_development_dependency 'rspec', '~> 2.14'
32
33
  spec.add_development_dependency 'rubocop'
33
34
  spec.add_development_dependency 'sham_rack'
34
35
  spec.add_development_dependency 'sqlite3'
36
+ spec.add_development_dependency 'yard'
35
37
  end
@@ -2,6 +2,7 @@ require 'mime/types/full'
2
2
  require 'carrierwave/base64/version'
3
3
  require 'carrierwave/base64/exceptions'
4
4
  require 'carrierwave/base64/base64_string_io'
5
+ require 'carrierwave/base64/mounting_helper'
5
6
  require 'carrierwave/base64/adapter'
6
7
  require 'carrierwave/base64/railtie' if defined?(Rails)
7
8
 
@@ -1,42 +1,32 @@
1
1
  module Carrierwave
2
2
  module Base64
3
+ # Module with .mount_base64_uploader method, that is mixed in to
4
+ # ActiveRecord::Base or Mongoid::Document::ClassMethods
3
5
  module Adapter
4
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
5
- # rubocop:disable Metrics/CyclomaticComplexity
6
- # rubocop:disable Metrics/PerceivedComplexity
6
+ # Mounts the carrierwave uploader that can accept a base64 encoded
7
+ # string as input. It also accepts regular file uploads.
8
+ #
9
+ # @param attribute [Symbol] the attribute to mount this uploader on
10
+ # @param uploader_class [Carrierwave::Uploader] the uploader class to
11
+ # mount
12
+ # @param options [Hash{Symbol => Object}] a set of options
13
+ # @option options [Proc] :file_name Proc that must return a file name
14
+ # without extension
15
+ #
16
+ # @example Mount the uploader and specify the file name
17
+ # mount_base64_uploader :image, ImageUploader,
18
+ # file_name: -> (u) { u.username }
19
+ #
20
+ # @return [Symbol] the defined writer method name
7
21
  def mount_base64_uploader(attribute, uploader_class, options = {})
8
22
  mount_uploader attribute, uploader_class, options
9
23
  options[:file_name] ||= proc { attribute }
10
24
 
11
- if options[:file_name].is_a?(String)
12
- warn(
13
- '[Deprecation warning] Setting `file_name` option to a string is '\
14
- 'deprecated and will be removed in 3.0.0. If you want to keep the '\
15
- 'existing behaviour, wrap the string in a Proc'
16
- )
17
- end
25
+ Carrierwave::Base64::MountingHelper.check_for_deprecations(options)
18
26
 
19
- define_method "#{attribute}=" do |data|
20
- return if data == send(attribute).to_s
21
-
22
- if respond_to?("#{attribute}_will_change!") && data.present?
23
- send "#{attribute}_will_change!"
24
- end
25
-
26
- return super(data) unless data.is_a?(String) &&
27
- data.strip.start_with?('data')
28
-
29
- filename = if options[:file_name].respond_to?(:call)
30
- options[:file_name].call(self)
31
- else
32
- options[:file_name]
33
- end.to_s
34
-
35
- super Carrierwave::Base64::Base64StringIO.new(data.strip, filename)
36
- end
37
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
38
- # rubocop:enable Metrics/CyclomaticComplexity
39
- # rubocop:enable Metrics/PerceivedComplexity
27
+ Carrierwave::Base64::MountingHelper.define_writer(
28
+ self, attribute, options
29
+ )
40
30
  end
41
31
  end
42
32
  end
@@ -1,8 +1,28 @@
1
+ require 'mimemagic'
2
+ require 'mimemagic/overlay'
3
+
1
4
  module Carrierwave
2
5
  module Base64
6
+ # Class that decodes a base64 string, builds a StringIO for the
7
+ # decoded bytes, and extracts the file MIME type to build a file
8
+ # name with extension.
3
9
  class Base64StringIO < StringIO
4
- attr_accessor :file_extension, :file_name
10
+ # @return [String] the file name without extension
11
+ attr_reader :file_name
12
+
13
+ # @return [String] the file extension for the uploaded file
14
+ attr_reader :file_extension
5
15
 
16
+ # Returns a StringIO with decoded bytes from the base64 encoded
17
+ # string and builds a file name with extension for the uploaded file,
18
+ # based on the MIME type specified in the base64 encoded string.
19
+ #
20
+ # @param encoded_file [String] the base64 encoded file contents
21
+ # @param file_name [String] the file name without extention
22
+ #
23
+ # @raise [ArgumentError] If the base64 encoded string is empty
24
+ #
25
+ # @return [StringIO] StringIO with decoded bytes
6
26
  def initialize(encoded_file, file_name)
7
27
  description, encoded_bytes = encoded_file.split(',')
8
28
 
@@ -10,21 +30,28 @@ module Carrierwave
10
30
  raise ArgumentError if encoded_bytes.eql?('(null)')
11
31
 
12
32
  @file_name = file_name
13
- @file_extension = get_file_extension description
14
33
  bytes = ::Base64.decode64 encoded_bytes
34
+ @file_extension = get_file_extension description, bytes
15
35
 
16
36
  super bytes
17
37
  end
18
38
 
39
+ # Returns a file name with extension, based on the MIME type specified
40
+ # in the base64 encoded string.
41
+ #
42
+ # @return [String] File name with extention
19
43
  def original_filename
20
44
  File.basename("#{@file_name}.#{@file_extension}")
21
45
  end
22
46
 
23
47
  private
24
48
 
25
- def get_file_extension(description)
26
- content_type = description.split(';base64').first
27
- mime_type = MIME::Types[content_type].first
49
+ # Determine content type from input, with provided type as fallback
50
+ def get_file_extension(description, bytes)
51
+ detected_type = MimeMagic.by_magic(bytes)
52
+ content_type = (detected_type && detected_type.type) ||
53
+ description.split(';base64').first
54
+ mime_type = MIME::Types[content_type].last
28
55
  unless mime_type
29
56
  raise Carrierwave::Base64::UnknownMimeTypeError,
30
57
  "Unknown MIME type: #{content_type}"
@@ -1,5 +1,7 @@
1
1
  module Carrierwave
2
2
  module Base64
3
+ # Exception that gets raised when base64 encoded string
4
+ # is of unknown MIME type
3
5
  class UnknownMimeTypeError < ::ArgumentError; end
4
6
  end
5
7
  end
@@ -0,0 +1,63 @@
1
+ module Carrierwave
2
+ module Base64
3
+ # Module with helper functions for mounting uploaders
4
+ module MountingHelper
5
+ module_function
6
+
7
+ # Checks for deprecations and prints a warning if found any.
8
+ # @private
9
+ #
10
+ # @param options [Hash{Symbol => Object}] the uploader options
11
+ # @return [void]
12
+ def check_for_deprecations(options)
13
+ return unless options[:file_name].is_a?(String)
14
+
15
+ warn(
16
+ '[Deprecation warning] Setting `file_name` option to a string is '\
17
+ 'deprecated and will be removed in 3.0.0. If you want to keep the '\
18
+ 'existing behaviour, wrap the string in a Proc'
19
+ )
20
+ end
21
+
22
+ # Returns a file name for the uploaded file.
23
+ # @private
24
+ #
25
+ # @param model_instance [Object] the model instance object
26
+ # @param options [Hash{Symbol => Object}] the uploader options
27
+ # @return [String] File name without extension
28
+ def file_name(model_instance, options)
29
+ if options[:file_name].respond_to?(:call)
30
+ options[:file_name].call(model_instance)
31
+ else
32
+ options[:file_name]
33
+ end.to_s
34
+ end
35
+
36
+ # Defines an attribute writer method on the class with mounted uploader.
37
+ # @private
38
+ #
39
+ # @param klass [Class] the class with mounted uploader
40
+ # @param attr [Symbol] the attribute for which the writer will be defined
41
+ # @param options [Hash{Symbol => Object}] a set of options
42
+ # @return [Symbol] the defined writer method name
43
+ def define_writer(klass, attr, options)
44
+ klass.send(:define_method, "#{attr}=") do |data|
45
+ # rubocop:disable Lint/NonLocalExitFromIterator
46
+ return if data.to_s.empty? || data == send(attr).to_s
47
+
48
+ # rubocop:enable Lint/NonLocalExitFromIterator
49
+
50
+ send("#{attr}_will_change!") if respond_to?("#{attr}_will_change!")
51
+
52
+ return super(data) unless data.is_a?(String) &&
53
+ data.strip.start_with?('data')
54
+
55
+ super Carrierwave::Base64::Base64StringIO.new(
56
+ data.strip,
57
+ Carrierwave::Base64::MountingHelper.file_name(self, options)
58
+ )
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,5 +1,7 @@
1
1
  module Carrierwave
2
2
  module Base64
3
+ # Railtie class to load the carrierwave-base64 adapters
4
+ # Loads adapters for ActiveRecord and Mongoid
3
5
  class Railtie < Rails::Railtie
4
6
  ActiveSupport.on_load :active_record do
5
7
  ActiveRecord::Base.extend Carrierwave::Base64::Adapter
@@ -1,5 +1,5 @@
1
1
  module Carrierwave
2
2
  module Base64
3
- VERSION = '2.7.0'.freeze
3
+ VERSION = '2.8.0'.freeze
4
4
  end
5
5
  end
@@ -30,11 +30,10 @@ RSpec.describe Carrierwave::Base64::Adapter do
30
30
 
31
31
  it 'creates a file' do
32
32
  subject.save!
33
- subject.reload
34
33
 
35
34
  expect(
36
35
  subject.image.current_path
37
- ).to eq file_path('../uploads', 'image.jpeg')
36
+ ).to eq file_path('../uploads', 'image.png')
38
37
  end
39
38
  end
40
39
  end
@@ -86,7 +85,6 @@ RSpec.describe Carrierwave::Base64::Adapter do
86
85
 
87
86
  it 'saves the file' do
88
87
  subject.save!
89
- subject.reload
90
88
 
91
89
  expect(
92
90
  subject.image.current_path
@@ -103,11 +101,10 @@ RSpec.describe Carrierwave::Base64::Adapter do
103
101
 
104
102
  it 'creates a file' do
105
103
  subject.save!
106
- subject.reload
107
104
 
108
105
  expect(
109
106
  subject.image.current_path
110
- ).to eq file_path('../uploads', 'batman.jpeg')
107
+ ).to eq file_path('../uploads', 'batman.png')
111
108
  end
112
109
 
113
110
  it 'sets will_change for the attribute' do
@@ -126,10 +123,9 @@ RSpec.describe Carrierwave::Base64::Adapter do
126
123
  it 'should invoke the file_name proc upon each upload' do
127
124
  subject.save!
128
125
  another_subject.save!
129
- another_subject.reload
130
126
  expect(
131
127
  another_subject.image.current_path
132
- ).to eq file_path('../uploads', 'robin.jpeg')
128
+ ).to eq file_path('../uploads', 'robin.png')
133
129
  end
134
130
  end
135
131
  end
@@ -140,21 +136,39 @@ RSpec.describe Carrierwave::Base64::Adapter do
140
136
  file_path('fixtures', 'base64_image.fixture')
141
137
  ).strip
142
138
  subject.save!
143
- subject.reload
144
139
  end
145
140
 
146
141
  it 'keeps the file when setting the attribute to existing value' do
147
- expect(File.exist?(subject.reload.image.file.file)).to be_truthy
142
+ expect(File.exist?(subject.image.file.file)).to be_truthy
148
143
  subject.update!(image: subject.image.to_s)
149
- expect(File.exist?(subject.reload.image.file.file)).to be_truthy
144
+ expect(File.exist?(subject.image.file.file)).to be_truthy
150
145
  end
151
146
 
152
147
  it 'removes files when remove_* is set to true' do
153
148
  subject.remove_image = true
154
149
  subject.save!
155
- expect(subject.reload.image.file).to be_nil
150
+ expect(subject.image.file).to be_nil
156
151
  end
157
152
  end
158
153
  end
154
+
155
+ context 'models with presence validation on attribute with uploader' do
156
+ subject do
157
+ User.validates(:image, presence: true)
158
+ User.mount_base64_uploader(:image, uploader)
159
+ User.new
160
+ end
161
+
162
+ before(:each) do
163
+ subject.image = File.read(
164
+ file_path('fixtures', 'base64_image.fixture')
165
+ ).strip
166
+ subject.save!
167
+ end
168
+
169
+ it 'gives no false positive on presence validation' do
170
+ expect { subject.update!(username: 'new-username') }.not_to raise_error
171
+ end
172
+ end
159
173
  end
160
174
  end
@@ -2,17 +2,19 @@ RSpec.describe Carrierwave::Base64::Base64StringIO do
2
2
  %w[application/vnd.openxmlformats-officedocument.wordprocessingml.document
3
3
  image/jpeg application/pdf audio/mpeg].each do |content_type|
4
4
  context "correct #{content_type} data" do
5
- let(:data) do
6
- "data:#{content_type};base64,/9j/4AAQSkZJRgABAQEASABKdhH//2Q=="
7
- end
8
-
9
5
  let(:file_extension) do
10
6
  MIME::Types[content_type].last.preferred_extension
11
7
  end
12
8
 
9
+ let(:data) do
10
+ file_name = "test.#{file_extension}"
11
+ bytes = File.read(file_path('fixtures', file_name))
12
+ "data:#{content_type};base64,#{::Base64.encode64(bytes)}"
13
+ end
14
+
13
15
  subject { described_class.new data, 'file' }
14
16
 
15
- it 'determines the file format from the Data URI content type' do
17
+ it 'determines the file format from the content type' do
16
18
  expect(subject.file_extension).to eql(file_extension)
17
19
  end
18
20
 
@@ -1 +1 @@
1
- data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
1
+ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
Binary file
Binary file
Binary file
Binary file
File without changes
@@ -14,7 +14,6 @@ require 'carrierwave/mongoid'
14
14
 
15
15
  require 'carrierwave/base64'
16
16
 
17
- ActiveRecord::Base.raise_in_transactional_callbacks = true
18
17
  ActiveRecord::Base.establish_connection(
19
18
  adapter: 'sqlite3',
20
19
  database: ':memory:'
@@ -29,3 +28,15 @@ def file_path(*paths)
29
28
  end
30
29
 
31
30
  CarrierWave.root = ''
31
+
32
+ # Add preferred file types similar to how users would implement custom types
33
+ content_types = {
34
+ 'audio/mpeg' => 'mp3'
35
+ }
36
+ content_types.each do |content_type, extension|
37
+ MIME::Types.add(
38
+ MIME::Type.new(content_type).tap do |type|
39
+ type.preferred_extension = extension
40
+ end
41
+ )
42
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carrierwave-base64
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yury Lebedev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-12 00:00:00.000000000 Z
11
+ date: 2018-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: carrierwave
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mimemagic
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.2
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.2
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +114,14 @@ dependencies:
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '4'
117
+ version: '5'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '4'
124
+ version: '5'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rake
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +192,20 @@ dependencies:
178
192
  - - ">="
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: yard
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
181
209
  description: This gem can be useful, if you need to upload files to your API from
182
210
  mobile devises.
183
211
  email:
@@ -200,12 +228,17 @@ files:
200
228
  - lib/carrierwave/base64/adapter.rb
201
229
  - lib/carrierwave/base64/base64_string_io.rb
202
230
  - lib/carrierwave/base64/exceptions.rb
231
+ - lib/carrierwave/base64/mounting_helper.rb
203
232
  - lib/carrierwave/base64/railtie.rb
204
233
  - lib/carrierwave/base64/version.rb
205
234
  - spec/adapter_spec.rb
206
235
  - spec/base64_string_io_spec.rb
207
236
  - spec/fixtures/base64_image.fixture
208
- - spec/fixtures/test.jpg
237
+ - spec/fixtures/test.docx
238
+ - spec/fixtures/test.jpeg
239
+ - spec/fixtures/test.mp3
240
+ - spec/fixtures/test.pdf
241
+ - spec/fixtures/test.png
209
242
  - spec/spec_helper.rb
210
243
  - spec/support/custom_expectations/warn_expectation.rb
211
244
  - spec/support/models.rb
@@ -230,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
263
  version: '0'
231
264
  requirements: []
232
265
  rubyforge_project:
233
- rubygems_version: 2.7.3
266
+ rubygems_version: 2.7.6
234
267
  signing_key:
235
268
  specification_version: 4
236
269
  summary: Upload images encoded as base64 to carrierwave.
@@ -238,7 +271,11 @@ test_files:
238
271
  - spec/adapter_spec.rb
239
272
  - spec/base64_string_io_spec.rb
240
273
  - spec/fixtures/base64_image.fixture
241
- - spec/fixtures/test.jpg
274
+ - spec/fixtures/test.docx
275
+ - spec/fixtures/test.jpeg
276
+ - spec/fixtures/test.mp3
277
+ - spec/fixtures/test.pdf
278
+ - spec/fixtures/test.png
242
279
  - spec/spec_helper.rb
243
280
  - spec/support/custom_expectations/warn_expectation.rb
244
281
  - spec/support/models.rb