saviour 0.4.5 → 0.4.6

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -18
  3. data/README.md +6 -9
  4. data/lib/saviour.rb +8 -0
  5. data/lib/saviour/base_uploader.rb +17 -4
  6. data/lib/saviour/config.rb +1 -1
  7. data/lib/saviour/db_helpers.rb +69 -0
  8. data/lib/saviour/file.rb +76 -26
  9. data/lib/saviour/integrator.rb +8 -3
  10. data/lib/saviour/life_cycle.rb +60 -12
  11. data/lib/saviour/local_storage.rb +35 -12
  12. data/lib/saviour/model.rb +12 -3
  13. data/lib/saviour/s3_storage.rb +46 -17
  14. data/lib/saviour/source_filename_extractor.rb +6 -1
  15. data/lib/saviour/uploader/processors_runner.rb +29 -2
  16. data/lib/saviour/url_source.rb +7 -3
  17. data/lib/saviour/validator.rb +34 -4
  18. data/lib/saviour/version.rb +1 -1
  19. data/saviour.gemspec +4 -3
  20. data/spec/feature/{allow_overriding_attached_as_method.rb → allow_overriding_attached_as_method_spec.rb} +0 -0
  21. data/spec/feature/crud_workflows_spec.rb +26 -10
  22. data/spec/feature/dirty_spec.rb +29 -21
  23. data/spec/feature/memory_usage_spec.rb +84 -0
  24. data/spec/feature/{processors_api.rb → processors_api_spec.rb} +22 -5
  25. data/spec/feature/{rewind_source_before_read.rb → rewind_source_before_read_spec.rb} +0 -0
  26. data/spec/feature/transactional_behavior_spec.rb +147 -0
  27. data/spec/feature/{uploader_declaration.rb → uploader_declaration_spec.rb} +0 -0
  28. data/spec/feature/validations_spec.rb +19 -0
  29. data/spec/feature/with_copy_spec.rb +43 -0
  30. data/spec/models/base_uploader_spec.rb +12 -33
  31. data/spec/models/config_spec.rb +2 -2
  32. data/spec/models/file_spec.rb +19 -47
  33. data/spec/models/local_storage_spec.rb +13 -34
  34. data/spec/models/s3_storage_spec.rb +12 -37
  35. data/spec/models/url_source_spec.rb +4 -4
  36. data/spec/spec_helper.rb +4 -0
  37. metadata +29 -14
  38. data/gemfiles/4.0.gemfile +0 -9
  39. data/gemfiles/4.1.gemfile +0 -9
  40. data/gemfiles/4.2.gemfile +0 -9
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Saviour::Config do
4
4
  describe "#storage" do
5
5
  it do
6
- expect { Saviour::Config.storage.anything }.to raise_error(RuntimeError)
6
+ expect { Saviour::Config.storage.anything }.to raise_error(Saviour::ConfigurationError)
7
7
  end
8
8
 
9
9
  it do
@@ -31,7 +31,7 @@ describe Saviour::Config do
31
31
  Thread.main.thread_variable_set("Saviour::Config", nil)
32
32
 
33
33
  Thread.new {
34
- expect { Saviour::Config.storage.anything }.to raise_error(RuntimeError)
34
+ expect { Saviour::Config.storage.anything }.to raise_error(Saviour::ConfigurationError)
35
35
  }.join
36
36
  end
37
37
 
@@ -29,7 +29,7 @@ describe Saviour::File do
29
29
  store_dir { "/store/dir" }
30
30
  } }
31
31
 
32
- let(:example_file) { double(read: "some file contents", path: "/my/path", rewind: nil) }
32
+ let(:example_file) { double(read: "some file contents", filename: "file.txt", rewind: nil) }
33
33
 
34
34
  let(:dummy_class) {
35
35
  klass = Class.new
@@ -51,33 +51,36 @@ describe Saviour::File do
51
51
 
52
52
  it "shows error if assigned object do not respond to :read" do
53
53
  file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
54
- expect { file.assign(6) }.to raise_error(RuntimeError)
54
+ expect { file.assign(6) }.to raise_error(Saviour::SourceError)
55
55
  end
56
56
  end
57
57
 
58
58
  describe "#write" do
59
59
  it "fails without source" do
60
60
  file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
61
- expect { file.write }.to raise_error(RuntimeError)
61
+ expect { file.write }.to raise_error(Saviour::MissingSource)
62
62
  end
63
63
 
64
64
  describe "filename used" do
65
65
  it "is extracted from original_filename if possible" do
66
66
  file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
67
- file.assign(double(read: "contents", original_filename: 'original.jpg', path: "/my/path/my_file.zip", rewind: nil))
67
+ file.assign(double(read: "contents", original_filename: 'original.jpg', rewind: nil))
68
68
  uploader = double
69
69
  allow(file).to receive(:uploader).and_return(uploader)
70
- expect(uploader).to receive(:write).with("contents", "original.jpg")
70
+ expect(uploader).to receive(:_process_as_contents).with("contents", "original.jpg")
71
71
  file.write
72
72
  end
73
73
 
74
74
  it "is extracted from path if possible" do
75
75
  file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
76
- file.assign(double(read: "contents", path: "/my/path/my_file.zip", rewind: nil))
77
- uploader = double
78
- allow(file).to receive(:uploader).and_return(uploader)
79
- expect(uploader).to receive(:write).with("contents", "my_file.zip")
80
- file.write
76
+ with_test_file("example.xml") do |xml_file|
77
+ dummy_file = double(read: "contents", path: xml_file.path, rewind: nil)
78
+ file.assign(dummy_file)
79
+ uploader = double
80
+ allow(file).to receive(:uploader).and_return(uploader)
81
+ expect(uploader).to receive(:_process_as_file).with(an_instance_of(Tempfile), File.basename(xml_file.path))
82
+ file.write
83
+ end
81
84
  end
82
85
 
83
86
  it "is random if cannot be guessed" do
@@ -86,18 +89,18 @@ describe Saviour::File do
86
89
  allow(SecureRandom).to receive(:hex).and_return("stubbed-random")
87
90
  uploader = double
88
91
  allow(file).to receive(:uploader).and_return(uploader)
89
- expect(uploader).to receive(:write).with("contents", "stubbed-random")
92
+ expect(uploader).to receive(:_process_as_contents).with("contents", "stubbed-random")
90
93
  file.write
91
94
  end
92
95
  end
93
96
 
94
- it "returns the path" do
97
+ it "returns the final contents and path" do
95
98
  object = dummy_class.new
96
99
  file = Saviour::File.new(uploader_klass, object, :file)
97
- file.assign(double(read: "contents", path: "/my/path/my_file.zip", rewind: nil))
100
+ file.assign(double(read: "contents", filename: "my_file.zip", rewind: nil))
98
101
  uploader = double
99
102
  allow(file).to receive(:uploader).and_return(uploader)
100
- expect(uploader).to receive(:write).with("contents", "my_file.zip").and_return("/store/dir/my_file.zip")
103
+ expect(uploader).to receive(:_process_as_contents).with("contents", "my_file.zip").and_return(['contents', "/store/dir/my_file.zip"])
101
104
  expect(file.write).to eq "/store/dir/my_file.zip"
102
105
  end
103
106
  end
@@ -114,12 +117,12 @@ describe Saviour::File do
114
117
 
115
118
  it "is cleared after persisting" do
116
119
  file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
117
- file.assign(double(read: "contents", path: "/my/path/my_file.zip", rewind: nil))
120
+ file.assign(double(read: "contents", filename: "my_file.zip", rewind: nil))
118
121
  expect(file).to be_changed
119
122
 
120
123
  uploader = double
121
124
  allow(file).to receive(:uploader).and_return(uploader)
122
- expect(uploader).to receive(:write).and_return("/some/path")
125
+ expect(uploader).to receive(:_process_as_contents).and_return("/some/path")
123
126
  file.write
124
127
 
125
128
  expect(file).not_to be_changed
@@ -139,37 +142,6 @@ describe Saviour::File do
139
142
  end
140
143
  end
141
144
 
142
- describe "#with_copy" do
143
- it "provides a copy of the stored file" do
144
- file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
145
- file.set_path! "/path/file.jpg"
146
- allow(file).to receive(:read).and_return("some contents")
147
-
148
- file.with_copy do |tmpfile|
149
- expect(tmpfile.read).to eq "some contents"
150
- end
151
- end
152
-
153
- it "deletes the copied file even on exception" do
154
- file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
155
- file.set_path! "/path/file.jpg"
156
- allow(file).to receive(:read).and_return("some contents")
157
-
158
- mocked_tmpfile = double(binmode: "", rewind: "", flush: "", write: "")
159
- allow(Tempfile).to receive(:open).and_yield(mocked_tmpfile)
160
-
161
- expect(mocked_tmpfile).to receive(:close)
162
- expect(mocked_tmpfile).to receive(:delete)
163
-
164
- test_exception = Class.new(StandardError)
165
-
166
- begin
167
- file.with_copy { |_| raise(test_exception, "some exception within the block") }
168
- rescue test_exception
169
- end
170
- end
171
- end
172
-
173
145
  describe "#blank?" do
174
146
  it "it's true when not yet assigned nor persisted" do
175
147
  file = Saviour::File.new(uploader_klass, dummy_class.new, :file)
@@ -21,40 +21,19 @@ describe Saviour::LocalStorage do
21
21
  end
22
22
  end
23
23
 
24
- describe "overwritting an existing file" do
25
- context "with overwrite protection" do
26
- it "raises an error" do
27
- path = File.join(@tmpdir, destination_path)
28
-
29
- FileUtils.mkdir_p(File.dirname(path))
30
- File.write(path, "some dummy content")
31
- expect(File.file?(path)).to be_truthy
32
-
33
- with_test_file("camaloon.jpg") do |file, _|
34
- contents = file.read
35
- expect { subject.write(contents, destination_path) }.to raise_error(RuntimeError)
36
- end
37
- end
38
- end
39
-
40
- context "without overwrite protection" do
41
- subject { Saviour::LocalStorage.new(local_prefix: @tmpdir, overwrite_protection: false) }
42
-
43
- it do
44
- path = File.join(@tmpdir, destination_path)
24
+ it "overwrites the existing file" do
25
+ path = File.join(@tmpdir, destination_path)
45
26
 
46
- FileUtils.mkdir_p(File.dirname(path))
47
- File.write(path, "some dummy content")
48
- expect(File.file?(path)).to be_truthy
27
+ FileUtils.mkdir_p(File.dirname(path))
28
+ File.write(path, "some dummy content")
29
+ expect(File.file?(path)).to be_truthy
49
30
 
50
- with_test_file("camaloon.jpg") do |file, _|
51
- contents = file.read
52
- subject.write(contents, destination_path)
31
+ with_test_file("camaloon.jpg") do |file, _|
32
+ contents = file.read
33
+ subject.write(contents, destination_path)
53
34
 
54
- expect(File.file?(path)).to be_truthy
55
- expect(File.read(path)).to eq contents
56
- end
57
- end
35
+ expect(File.file?(path)).to be_truthy
36
+ expect(File.read(path)).to eq contents
58
37
  end
59
38
  end
60
39
  end
@@ -67,7 +46,7 @@ describe Saviour::LocalStorage do
67
46
  end
68
47
 
69
48
  it "fails if the file do not exists" do
70
- expect { subject.read("nope.rar") }.to raise_error(RuntimeError)
49
+ expect { subject.read("nope.rar") }.to raise_error(Saviour::FileNotPresent)
71
50
  end
72
51
  end
73
52
 
@@ -82,7 +61,7 @@ describe Saviour::LocalStorage do
82
61
  end
83
62
 
84
63
  it "fails if the file do not exists" do
85
- expect { subject.delete("nope.rar") }.to raise_error(RuntimeError)
64
+ expect { subject.delete("nope.rar") }.to raise_error(Saviour::FileNotPresent)
86
65
  end
87
66
 
88
67
  it "does not leave an empty dir behind" do
@@ -124,7 +103,7 @@ describe Saviour::LocalStorage do
124
103
  with_test_file("camaloon.jpg") do |file, _|
125
104
  expect {
126
105
  subject.public_url(File.basename(file.path))
127
- }.to raise_error(RuntimeError)
106
+ }.to raise_error(Saviour::LocalStorage::MissingPublicUrlPrefix)
128
107
  end
129
108
  end
130
109
  end
@@ -32,43 +32,18 @@ describe Saviour::S3Storage do
32
32
  expect { subject.write("contents", key) }.to raise_error.with_message(/The key in S3 must be at max 1024 bytes, this key is too big/)
33
33
  end
34
34
 
35
- describe "overwritting" do
36
- context "without overwrite protection" do
37
- subject {
38
- Saviour::S3Storage.new(
39
- bucket: "fake-bucket",
40
- aws_access_key_id: "stub",
41
- aws_secret_access_key: "stub",
42
- public_url_prefix: "https://fake-bucket.s3.amazonaws.com",
43
- overwrite_protection: false
44
- )
45
- }
46
-
47
- it "overwrites the existing file" do
48
- mocked_s3.write("some dummy contents", destination_path)
49
- expect(mocked_s3.exists?(destination_path)).to be_truthy
50
-
51
- with_test_file("camaloon.jpg") do |file, _|
52
- contents = file.read
53
- subject.write(contents, destination_path)
54
- expect(mocked_s3.read(destination_path)).to eq contents
55
- end
56
- end
57
- end
58
-
59
- context "with overwrite protection" do
60
- it "raises an exception" do
61
- mocked_s3.write("some dummy contents", destination_path)
62
- expect(mocked_s3.exists?(destination_path)).to be_truthy
35
+ it "overwrites the existing file" do
36
+ mocked_s3.write("some dummy contents", destination_path)
37
+ expect(mocked_s3.exists?(destination_path)).to be_truthy
63
38
 
64
- with_test_file("camaloon.jpg") do |file, _|
65
- contents = file.read
66
- expect { subject.write(contents, destination_path) }.to raise_error(RuntimeError)
67
- end
68
- end
39
+ with_test_file("camaloon.jpg") do |file, _|
40
+ contents = file.read
41
+ subject.write(contents, destination_path)
42
+ expect(mocked_s3.read(destination_path)).to eq contents
69
43
  end
70
44
  end
71
45
 
46
+
72
47
  it "ignores leading slash" do
73
48
  subject.write("trash contents", "/folder/file.out")
74
49
  expect(subject.exists?("folder/file.out")).to be_truthy
@@ -77,7 +52,7 @@ describe Saviour::S3Storage do
77
52
  end
78
53
 
79
54
  describe "fog create options" do
80
- subject { Saviour::S3Storage.new(bucket: "fake-bucket", aws_access_key_id: "stub", aws_secret_access_key: "stub", public_url_prefix: "https://fake-bucket.s3.amazonaws.com", create_options: {'Cache-Control' => 'max-age=31536000'}) }
55
+ subject { Saviour::S3Storage.new(bucket: "fake-bucket", aws_access_key_id: "stub", aws_secret_access_key: "stub", public_url_prefix: "https://fake-bucket.s3.amazonaws.com", create_options: { 'Cache-Control' => 'max-age=31536000' }) }
81
56
 
82
57
  it "uses passed options to create new files in S3" do
83
58
  with_test_file("camaloon.jpg") do |file, _|
@@ -103,7 +78,7 @@ describe Saviour::S3Storage do
103
78
  end
104
79
 
105
80
  it "fails if the file do not exists" do
106
- expect { subject.read("nope.rar") }.to raise_error(RuntimeError)
81
+ expect { subject.read("nope.rar") }.to raise_error(Saviour::FileNotPresent)
107
82
  end
108
83
  end
109
84
 
@@ -122,7 +97,7 @@ describe Saviour::S3Storage do
122
97
  end
123
98
 
124
99
  it "fails if the file do not exists" do
125
- expect { subject.delete("nope.rar") }.to raise_error(RuntimeError)
100
+ expect { subject.delete("nope.rar") }.to raise_error(Saviour::FileNotPresent)
126
101
  end
127
102
  end
128
103
 
@@ -152,7 +127,7 @@ describe Saviour::S3Storage do
152
127
  with_test_file("camaloon.jpg") do |file, _|
153
128
  contents = file.read
154
129
  mocked_s3.write(contents, destination_path)
155
- expect { subject.public_url(destination_path) }.to raise_error(RuntimeError)
130
+ expect { subject.public_url(destination_path) }.to raise_error(Saviour::S3Storage::MissingPublicUrlPrefix)
156
131
  end
157
132
  end
158
133
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Saviour::UrlSource do
4
4
  describe "initialization" do
5
5
  it "fails if no valid uri" do
6
- expect { Saviour::UrlSource.new("%^7QQ#%%@#@@") }.to raise_error(ArgumentError).with_message(/is not a valid URI/)
6
+ expect { Saviour::UrlSource.new("%^7QQ#%%@#@@") }.to raise_error(Saviour::UrlSource::InvalidUrl).with_message(/is not a valid URI/)
7
7
  end
8
8
 
9
9
  it "does not fail if provided a valid uri" do
@@ -23,7 +23,7 @@ describe Saviour::UrlSource do
23
23
  allow(Net::HTTP).to receive(:get_response).and_return(Net::HTTPNotFound)
24
24
 
25
25
  a = Saviour::UrlSource.new("http://aboubaosdubioaubosdubaou.com/path/file.jpg")
26
- expect { a.read }.to raise_error(RuntimeError).with_message(/failed after 3 attempts/)
26
+ expect { a.read }.to raise_error(Saviour::UrlSource::ConnectionFailed).with_message(/failed after 3 attempts/)
27
27
  end
28
28
 
29
29
  it "retries the request 3 times on error" do
@@ -54,7 +54,7 @@ describe Saviour::UrlSource do
54
54
  expect(response).to receive(:[]).with("location").exactly(10).times.and_return("http://example.org")
55
55
  expect(Net::HTTP).to receive(:get_response).exactly(10).times.and_return(response)
56
56
 
57
- expect { Saviour::UrlSource.new("http://faked.blabla").read }.to raise_error(RuntimeError).with_message(/Max number of allowed redirects reached \(10\) when resolving/)
57
+ expect { Saviour::UrlSource.new("http://faked.blabla").read }.to raise_error(Saviour::UrlSource::TooManyRedirects).with_message(/Max number of allowed redirects reached \(10\) when resolving/)
58
58
  end
59
59
 
60
60
  it "fails if the redirected location is not a valid URI" do
@@ -63,7 +63,7 @@ describe Saviour::UrlSource do
63
63
 
64
64
  expect(Net::HTTP).to receive(:get_response).and_return(response)
65
65
 
66
- expect { Saviour::UrlSource.new("http://faked.blabla").read }.to raise_error(ArgumentError).with_message(/is not a valid URI/)
66
+ expect { Saviour::UrlSource.new("http://faked.blabla").read }.to raise_error(Saviour::UrlSource::InvalidUrl).with_message(/is not a valid URI/)
67
67
  end
68
68
  end
69
69
  end
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,7 @@ require 'bundler/setup'
5
5
  require 'rspec'
6
6
  require 'active_record'
7
7
  require 'sqlite3'
8
+ require 'get_process_mem'
8
9
 
9
10
  require File.expand_path("../../lib/saviour", __FILE__)
10
11
 
@@ -43,6 +44,9 @@ RSpec.configure do |config|
43
44
  }
44
45
  end
45
46
 
47
+ config.before do
48
+ Test.delete_all
49
+ end
46
50
  config.after { Fog::Mock.reset }
47
51
  end
48
52
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saviour
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roger Campos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-06 00:00:00.000000000 Z
11
+ date: 2018-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
19
+ version: '5.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.0'
26
+ version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4.0'
33
+ version: '5.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '4.0'
40
+ version: '5.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: get_process_mem
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  description: File storage handler following active record model lifecycle
140
154
  email:
141
155
  - roger@rogercampos.com
@@ -150,14 +164,12 @@ files:
150
164
  - LICENSE.txt
151
165
  - README.md
152
166
  - Rakefile
153
- - gemfiles/4.0.gemfile
154
- - gemfiles/4.1.gemfile
155
- - gemfiles/4.2.gemfile
156
167
  - gemfiles/5.0.gemfile
157
168
  - gemfiles/5.1.gemfile
158
169
  - lib/saviour.rb
159
170
  - lib/saviour/base_uploader.rb
160
171
  - lib/saviour/config.rb
172
+ - lib/saviour/db_helpers.rb
161
173
  - lib/saviour/file.rb
162
174
  - lib/saviour/integrator.rb
163
175
  - lib/saviour/life_cycle.rb
@@ -173,17 +185,20 @@ files:
173
185
  - lib/saviour/validator.rb
174
186
  - lib/saviour/version.rb
175
187
  - saviour.gemspec
176
- - spec/feature/allow_overriding_attached_as_method.rb
188
+ - spec/feature/allow_overriding_attached_as_method_spec.rb
177
189
  - spec/feature/crud_workflows_spec.rb
178
190
  - spec/feature/dirty_spec.rb
179
191
  - spec/feature/follow_file_spec.rb
180
192
  - spec/feature/halt_processor_spec.rb
193
+ - spec/feature/memory_usage_spec.rb
181
194
  - spec/feature/persisted_path_spec.rb
182
- - spec/feature/processors_api.rb
195
+ - spec/feature/processors_api_spec.rb
183
196
  - spec/feature/reload_model_spec.rb
184
- - spec/feature/rewind_source_before_read.rb
185
- - spec/feature/uploader_declaration.rb
197
+ - spec/feature/rewind_source_before_read_spec.rb
198
+ - spec/feature/transactional_behavior_spec.rb
199
+ - spec/feature/uploader_declaration_spec.rb
186
200
  - spec/feature/validations_spec.rb
201
+ - spec/feature/with_copy_spec.rb
187
202
  - spec/models/base_uploader_spec.rb
188
203
  - spec/models/config_spec.rb
189
204
  - spec/models/file_spec.rb
@@ -209,7 +224,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
209
224
  requirements:
210
225
  - - ">="
211
226
  - !ruby/object:Gem::Version
212
- version: 2.1.0
227
+ version: 2.2.0
213
228
  required_rubygems_version: !ruby/object:Gem::Requirement
214
229
  requirements:
215
230
  - - ">="