multipart-post 2.0.0 → 2.1.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 +7 -0
- data/.rspec +5 -0
- data/.travis.yml +17 -6
- data/.yardopts +6 -0
- data/Gemfile +0 -8
- data/History.txt +5 -1
- data/LICENSE +21 -0
- data/README.md +111 -61
- data/lib/composite_io.rb +10 -10
- data/lib/multipart_post.rb +1 -1
- data/lib/multipartable.rb +40 -21
- data/lib/net/http/post/multipart.rb +4 -3
- data/lib/parts.rb +38 -8
- data/multipart-post.gemspec +18 -17
- data/spec/composite_io_spec.rb +138 -0
- data/{test → spec}/multibyte.txt +0 -0
- data/{test/net/http/post/test_multipart.rb → spec/net/http/post/multipart_spec.rb} +66 -53
- data/spec/parts_spec.rb +102 -0
- data/spec/spec_helper.rb +29 -0
- metadata +75 -34
- data/test/test_composite_io.rb +0 -115
- data/test/test_parts.rb +0 -86
data/multipart-post.gemspec
CHANGED
@@ -2,21 +2,22 @@
|
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
3
|
require "multipart_post"
|
4
4
|
|
5
|
-
Gem::Specification.new do |
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "multipart-post"
|
7
|
+
spec.version = MultipartPost::VERSION
|
8
|
+
spec.authors = ["Nick Sieger", "Samuel Williams"]
|
9
|
+
spec.email = ["nick@nicksieger.com", "samuel.williams@oriontransfer.co.nz"]
|
10
|
+
spec.homepage = "https://github.com/nicksieger/multipart-post"
|
11
|
+
spec.summary = %q{A multipart form post accessory for Net::HTTP.}
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.description = %q{Use with Net::HTTP to do multipart form postspec. IO values that have #content_type, #original_filename, and #local_path will be posted as a binary file.}
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split("\n")
|
16
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency 'bundler', ['>= 1.3', '< 3']
|
21
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
22
|
+
spec.add_development_dependency 'rake'
|
22
23
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# Copyright, 2012, by Nick Sieger.
|
2
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'composite_io'
|
23
|
+
require 'stringio'
|
24
|
+
require 'timeout'
|
25
|
+
|
26
|
+
RSpec.shared_context "composite io" do
|
27
|
+
it "test_full_read_from_several_ios" do
|
28
|
+
expect(subject.read).to be == 'the quick brown fox'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "test_partial_read" do
|
32
|
+
expect(subject.read(9)).to be == 'the quick'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "test_partial_read_to_boundary" do
|
36
|
+
expect(subject.read(10)).to be == 'the quick '
|
37
|
+
end
|
38
|
+
|
39
|
+
it "test_read_with_size_larger_than_available" do
|
40
|
+
expect(subject.read(32)).to be == 'the quick brown fox'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "test_read_into_buffer" do
|
44
|
+
buf = ''
|
45
|
+
subject.read(nil, buf)
|
46
|
+
expect(buf).to be == 'the quick brown fox'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "test_multiple_reads" do
|
50
|
+
expect(subject.read(4)).to be == 'the '
|
51
|
+
expect(subject.read(4)).to be == 'quic'
|
52
|
+
expect(subject.read(4)).to be == 'k br'
|
53
|
+
expect(subject.read(4)).to be == 'own '
|
54
|
+
expect(subject.read(4)).to be == 'fox'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "test_read_after_end" do
|
58
|
+
subject.read
|
59
|
+
expect(subject.read).to be == ""
|
60
|
+
end
|
61
|
+
|
62
|
+
it "test_read_after_end_with_amount" do
|
63
|
+
subject.read(32)
|
64
|
+
expect(subject.read(32)).to be_nil
|
65
|
+
end
|
66
|
+
|
67
|
+
it "test_second_full_read_after_rewinding" do
|
68
|
+
subject.read
|
69
|
+
subject.rewind
|
70
|
+
expect(subject.read).to be == 'the quick brown fox'
|
71
|
+
end
|
72
|
+
|
73
|
+
# Was apparently broken on JRuby due to http://jira.codehaus.org/browse/JRUBY-7109
|
74
|
+
it "test_compatible_with_copy_stream" do
|
75
|
+
target_io = StringIO.new
|
76
|
+
Timeout.timeout(1) do # Not sure why we need this in the spec?
|
77
|
+
IO.copy_stream(subject, target_io)
|
78
|
+
end
|
79
|
+
expect(target_io.string).to be == "the quick brown fox"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
RSpec.describe CompositeReadIO do
|
84
|
+
describe "generic io" do
|
85
|
+
subject {StringIO.new('the quick brown fox')}
|
86
|
+
|
87
|
+
include_context "composite io"
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "composite io" do
|
91
|
+
subject {CompositeReadIO.new(StringIO.new('the '), StringIO.new('quick '), StringIO.new('brown '), StringIO.new('fox'))}
|
92
|
+
|
93
|
+
include_context "composite io"
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "nested composite io" do
|
97
|
+
subject {CompositeReadIO.new(CompositeReadIO.new(StringIO.new('the '), StringIO.new('quick ')), StringIO.new('brown '), StringIO.new('fox'))}
|
98
|
+
|
99
|
+
include_context "composite io"
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "unicode composite io" do
|
103
|
+
let(:utf8_io) {File.open(File.dirname(__FILE__)+'/multibyte.txt')}
|
104
|
+
let(:binary_io) {StringIO.new("\x86")}
|
105
|
+
|
106
|
+
subject {CompositeReadIO.new(binary_io, utf8_io)}
|
107
|
+
|
108
|
+
it "test_read_from_multibyte" do
|
109
|
+
expect(subject.read).to be == "\x86\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\n".b
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "test_convert_error" do
|
114
|
+
expect do
|
115
|
+
UploadIO.convert!('tmp.txt', 'text/plain', 'tmp.txt', 'tmp.txt')
|
116
|
+
end.to raise_error(ArgumentError, /convert! has been removed/)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "test_empty" do
|
120
|
+
expect(subject.read).to be == ""
|
121
|
+
end
|
122
|
+
|
123
|
+
it "test_empty_limited" do
|
124
|
+
expect(subject.read(1)).to be_nil
|
125
|
+
end
|
126
|
+
|
127
|
+
it "test_empty_parts" do
|
128
|
+
io = CompositeReadIO.new(StringIO.new, StringIO.new('the '), StringIO.new, StringIO.new('quick'))
|
129
|
+
expect(io.read(3)).to be == "the"
|
130
|
+
expect(io.read(3)).to be == " qu"
|
131
|
+
expect(io.read(3)).to be == "ick"
|
132
|
+
end
|
133
|
+
|
134
|
+
it "test_all_empty_parts" do
|
135
|
+
io = CompositeReadIO.new(StringIO.new, StringIO.new)
|
136
|
+
expect(io.read(1)).to be_nil
|
137
|
+
end
|
138
|
+
end
|
data/{test → spec}/multibyte.txt
RENAMED
File without changes
|
@@ -5,42 +5,72 @@
|
|
5
5
|
#++
|
6
6
|
|
7
7
|
require 'net/http/post/multipart'
|
8
|
-
require 'test/unit'
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
RSpec.shared_context "net http multipart" do
|
10
|
+
let(:temp_file) {"temp.txt"}
|
11
|
+
let(:http_post) do
|
12
|
+
Struct.new("HTTPPost", :content_length, :body_stream, :content_type) do
|
13
|
+
def set_content_type(type, params = {})
|
14
|
+
self.content_type = type + params.map{|k,v|"; #{k}=#{v}"}.join('')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:each) do
|
20
|
+
File.delete(temp_file) rescue nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_results(post)
|
24
|
+
expect(post.content_length).to be > 0
|
25
|
+
expect(post.body_stream).to_not be_nil
|
26
|
+
|
27
|
+
expect(post['content-type']).to be == "multipart/form-data; boundary=#{post.boundary}"
|
28
|
+
|
29
|
+
body = post.body_stream.read
|
30
|
+
boundary_regex = Regexp.quote(post.boundary)
|
31
|
+
|
32
|
+
expect(body).to be =~ /1234567890/
|
33
|
+
|
34
|
+
# ensure there is at least one boundary
|
35
|
+
expect(body).to be =~ /^--#{boundary_regex}\r\n/
|
36
|
+
|
37
|
+
# ensure there is an epilogue
|
38
|
+
expect(body).to be =~ /^--#{boundary_regex}--\r\n/
|
39
|
+
expect(body).to be =~ /text\/plain/
|
40
|
+
|
41
|
+
if (body =~ /multivalueParam/)
|
42
|
+
expect(body.scan(/^.*multivalueParam.*$/).size).to be == 2
|
17
43
|
end
|
18
44
|
end
|
19
45
|
|
20
|
-
def
|
21
|
-
|
46
|
+
def assert_additional_headers_added(post, parts_headers)
|
47
|
+
post.body_stream.rewind
|
48
|
+
body = post.body_stream.read
|
49
|
+
parts_headers.each do |part, headers|
|
50
|
+
headers.each do |k,v|
|
51
|
+
expect(body).to be =~ /#{k}: #{v}/
|
52
|
+
end
|
53
|
+
end
|
22
54
|
end
|
55
|
+
end
|
23
56
|
|
24
|
-
|
57
|
+
RSpec.describe Net::HTTP::Post::Multipart do
|
58
|
+
include_context "net http multipart"
|
59
|
+
|
60
|
+
it "test_form_multipart_body" do
|
25
61
|
File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
|
26
62
|
@io = File.open(TEMP_FILE)
|
27
63
|
@io = UploadIO.new @io, "text/plain", TEMP_FILE
|
28
64
|
assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :foo => 'bar', :file => @io)
|
29
65
|
end
|
30
|
-
def test_form_multipart_body_put
|
31
|
-
File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
|
32
|
-
@io = File.open(TEMP_FILE)
|
33
|
-
@io = UploadIO.new @io, "text/plain", TEMP_FILE
|
34
|
-
assert_results Net::HTTP::Put::Multipart.new("/foo/bar", :foo => 'bar', :file => @io)
|
35
|
-
end
|
36
66
|
|
37
|
-
|
67
|
+
it "test_form_multipart_body_with_stringio" do
|
38
68
|
@io = StringIO.new("1234567890")
|
39
69
|
@io = UploadIO.new @io, "text/plain", TEMP_FILE
|
40
70
|
assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :foo => 'bar', :file => @io)
|
41
71
|
end
|
42
72
|
|
43
|
-
|
73
|
+
it "test_form_multiparty_body_with_parts_headers" do
|
44
74
|
@io = StringIO.new("1234567890")
|
45
75
|
@io = UploadIO.new @io, "text/plain", TEMP_FILE
|
46
76
|
parts = { :text => 'bar', :file => @io }
|
@@ -56,55 +86,38 @@ class Net::HTTP::Post::MultiPartTest < Test::Unit::TestCase
|
|
56
86
|
assert_additional_headers_added(request, headers[:parts])
|
57
87
|
end
|
58
88
|
|
59
|
-
|
89
|
+
it "test_form_multipart_body_with_array_value" do
|
60
90
|
File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
|
61
91
|
@io = File.open(TEMP_FILE)
|
62
92
|
@io = UploadIO.new @io, "text/plain", TEMP_FILE
|
63
93
|
params = {:foo => ['bar', 'quux'], :file => @io}
|
64
94
|
headers = { :parts => {
|
65
95
|
:foo => { "Content-Type" => "application/json; charset=UTF-8" } } }
|
66
|
-
post = Net::HTTP::Post::Multipart.new("/foo/bar", params, headers
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
assert post.body_stream
|
96
|
+
post = Net::HTTP::Post::Multipart.new("/foo/bar", params, headers)
|
97
|
+
|
98
|
+
expect(post.content_length).to be > 0
|
99
|
+
expect(post.body_stream).to_not be_nil
|
71
100
|
|
72
101
|
body = post.body_stream.read
|
73
|
-
|
74
|
-
|
102
|
+
expect(body.lines.grep(/name="foo"/).length).to be == 2
|
103
|
+
expect(body) =~ /Content-Type: application\/json; charset=UTF-8/
|
75
104
|
end
|
76
105
|
|
77
|
-
|
106
|
+
it "test_form_multipart_body_with_arrayparam" do
|
78
107
|
File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
|
79
108
|
@io = File.open(TEMP_FILE)
|
80
109
|
@io = UploadIO.new @io, "text/plain", TEMP_FILE
|
81
110
|
assert_results Net::HTTP::Post::Multipart.new("/foo/bar", :multivalueParam => ['bar','bah'], :file => @io)
|
82
111
|
end
|
112
|
+
end
|
83
113
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
assert body =~ /^--#{boundary_regex}\r\n/
|
93
|
-
# ensure there is an epilogue
|
94
|
-
assert body =~ /^--#{boundary_regex}--\r\n/
|
95
|
-
assert body =~ /text\/plain/
|
96
|
-
if (body =~ /multivalueParam/)
|
97
|
-
assert_equal 2, body.scan(/^.*multivalueParam.*$/).size
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def assert_additional_headers_added(post, parts_headers)
|
102
|
-
post.body_stream.rewind
|
103
|
-
body = post.body_stream.read
|
104
|
-
parts_headers.each do |part, headers|
|
105
|
-
headers.each do |k,v|
|
106
|
-
assert body =~ /#{k}: #{v}/
|
107
|
-
end
|
108
|
-
end
|
114
|
+
RSpec.describe Net::HTTP::Put::Multipart do
|
115
|
+
include_context "net http multipart"
|
116
|
+
|
117
|
+
it "test_form_multipart_body_put" do
|
118
|
+
File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
|
119
|
+
@io = File.open(TEMP_FILE)
|
120
|
+
@io = UploadIO.new @io, "text/plain", TEMP_FILE
|
121
|
+
assert_results Net::HTTP::Put::Multipart.new("/foo/bar", :foo => 'bar', :file => @io)
|
109
122
|
end
|
110
123
|
end
|
data/spec/parts_spec.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Copyright, 2012, by Nick Sieger.
|
2
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'parts'
|
23
|
+
require 'stringio'
|
24
|
+
require 'composite_io'
|
25
|
+
require 'tempfile'
|
26
|
+
|
27
|
+
MULTIBYTE = File.dirname(__FILE__)+'/multibyte.txt'
|
28
|
+
TEMP_FILE = "temp.txt"
|
29
|
+
|
30
|
+
module AssertPartLength
|
31
|
+
def assert_part_length(part)
|
32
|
+
bytes = part.to_io.read
|
33
|
+
bytesize = bytes.respond_to?(:bytesize) ? bytes.bytesize : bytes.length
|
34
|
+
expect(bytesize).to be == part.length
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
RSpec.describe Parts do
|
39
|
+
let(:string_with_content_type) do
|
40
|
+
Class.new(String) do
|
41
|
+
def content_type; 'application/data'; end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "test_file_with_upload_io" do
|
46
|
+
expect(Parts::Part.file?(UploadIO.new(__FILE__, "text/plain"))).to be true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "test_file_with_modified_string" do
|
50
|
+
expect(Parts::Part.file?(string_with_content_type.new("Hello"))).to be false
|
51
|
+
end
|
52
|
+
|
53
|
+
it "test_new_with_modified_string" do
|
54
|
+
expect(Parts::Part.new("boundary", "multibyte", string_with_content_type.new("Hello"))).to be_kind_of(Parts::ParamPart)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
RSpec.describe Parts::FilePart do
|
59
|
+
include AssertPartLength
|
60
|
+
|
61
|
+
before(:each) do
|
62
|
+
File.open(TEMP_FILE, "w") {|f| f << "1234567890"}
|
63
|
+
io = UploadIO.new(TEMP_FILE, "text/plain")
|
64
|
+
@part = Parts::FilePart.new("boundary", "afile", io)
|
65
|
+
end
|
66
|
+
|
67
|
+
after(:each) do
|
68
|
+
File.delete(TEMP_FILE) rescue nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it "test_correct_length" do
|
72
|
+
assert_part_length @part
|
73
|
+
end
|
74
|
+
|
75
|
+
it "test_multibyte_file_length" do
|
76
|
+
assert_part_length Parts::FilePart.new("boundary", "multibyte", UploadIO.new(MULTIBYTE, "text/plain"))
|
77
|
+
end
|
78
|
+
|
79
|
+
it "test_multibyte_filename" do
|
80
|
+
name = File.read(MULTIBYTE, 300)
|
81
|
+
file = Tempfile.new(name.respond_to?(:force_encoding) ? name.force_encoding("UTF-8") : name)
|
82
|
+
assert_part_length Parts::FilePart.new("boundary", "multibyte", UploadIO.new(file, "text/plain"))
|
83
|
+
file.close
|
84
|
+
end
|
85
|
+
|
86
|
+
it "test_force_content_type_header" do
|
87
|
+
part = Parts::FilePart.new("boundary", "afile", UploadIO.new(TEMP_FILE, "text/plain"), { "Content-Type" => "application/pdf" })
|
88
|
+
expect(part.to_io.read).to match(/Content-Type: application\/pdf/)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
RSpec.describe Parts::ParamPart do
|
93
|
+
include AssertPartLength
|
94
|
+
|
95
|
+
before(:each) do
|
96
|
+
@part = Parts::ParamPart.new("boundary", "multibyte", File.read(MULTIBYTE))
|
97
|
+
end
|
98
|
+
|
99
|
+
it "test_correct_length" do
|
100
|
+
assert_part_length @part
|
101
|
+
end
|
102
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
if ENV['COVERAGE']
|
3
|
+
begin
|
4
|
+
require 'simplecov'
|
5
|
+
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter "/spec/"
|
8
|
+
end
|
9
|
+
|
10
|
+
if ENV['TRAVIS']
|
11
|
+
require 'coveralls'
|
12
|
+
Coveralls.wear!
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
warn "Could not load simplecov: #{$!}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
require "bundler/setup"
|
20
|
+
require "multipart_post"
|
21
|
+
|
22
|
+
RSpec.configure do |config|
|
23
|
+
# Enable flags like --only-failures and --next-failure
|
24
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
25
|
+
|
26
|
+
config.expect_with :rspec do |c|
|
27
|
+
c.syntax = :expect
|
28
|
+
end
|
29
|
+
end
|