savon 0.7.9 → 0.8.0.beta.1
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.
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +2 -0
- data/CHANGELOG.md +332 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +37 -0
- data/Rakefile +28 -39
- data/autotest/discover.rb +1 -0
- data/lib/savon.rb +10 -31
- data/lib/savon/client.rb +116 -98
- data/lib/savon/core_ext/array.rb +36 -22
- data/lib/savon/core_ext/datetime.rb +15 -6
- data/lib/savon/core_ext/hash.rb +122 -94
- data/lib/savon/core_ext/object.rb +19 -11
- data/lib/savon/core_ext/string.rb +62 -57
- data/lib/savon/core_ext/symbol.rb +13 -5
- data/lib/savon/error.rb +6 -0
- data/lib/savon/global.rb +75 -0
- data/lib/savon/http/error.rb +42 -0
- data/lib/savon/soap.rb +8 -283
- data/lib/savon/soap/fault.rb +48 -0
- data/lib/savon/soap/request.rb +61 -0
- data/lib/savon/soap/response.rb +65 -0
- data/lib/savon/soap/xml.rb +132 -0
- data/lib/savon/version.rb +2 -2
- data/lib/savon/wsdl/document.rb +107 -0
- data/lib/savon/wsdl/parser.rb +90 -0
- data/lib/savon/wsdl/request.rb +35 -0
- data/lib/savon/wsse.rb +42 -104
- data/savon.gemspec +26 -0
- data/spec/fixtures/response/response_fixture.rb +26 -26
- data/spec/fixtures/response/xml/list.xml +18 -0
- data/spec/fixtures/wsdl/wsdl_fixture.rb +6 -0
- data/spec/fixtures/wsdl/wsdl_fixture.yml +4 -4
- data/spec/savon/client_spec.rb +274 -51
- data/spec/savon/core_ext/datetime_spec.rb +1 -1
- data/spec/savon/core_ext/hash_spec.rb +40 -4
- data/spec/savon/core_ext/object_spec.rb +1 -1
- data/spec/savon/core_ext/string_spec.rb +0 -12
- data/spec/savon/http/error_spec.rb +52 -0
- data/spec/savon/savon_spec.rb +90 -0
- data/spec/savon/soap/fault_spec.rb +80 -0
- data/spec/savon/soap/request_spec.rb +45 -0
- data/spec/savon/soap/response_spec.rb +153 -0
- data/spec/savon/soap/xml_spec.rb +249 -0
- data/spec/savon/soap_spec.rb +4 -177
- data/spec/savon/{wsdl_spec.rb → wsdl/document_spec.rb} +54 -17
- data/spec/savon/wsdl/request_spec.rb +15 -0
- data/spec/savon/wsse_spec.rb +123 -92
- data/spec/spec_helper.rb +19 -4
- data/spec/support/endpoint.rb +25 -0
- metadata +97 -97
- data/.autotest +0 -5
- data/CHANGELOG +0 -176
- data/README.rdoc +0 -64
- data/lib/savon/core_ext.rb +0 -8
- data/lib/savon/core_ext/net_http.rb +0 -19
- data/lib/savon/core_ext/uri.rb +0 -10
- data/lib/savon/logger.rb +0 -56
- data/lib/savon/request.rb +0 -138
- data/lib/savon/response.rb +0 -174
- data/lib/savon/wsdl.rb +0 -137
- data/lib/savon/wsdl_stream.rb +0 -85
- data/spec/basic_spec_helper.rb +0 -11
- data/spec/endpoint_helper.rb +0 -23
- data/spec/http_stubs.rb +0 -26
- data/spec/integration/http_basic_auth_spec.rb +0 -16
- data/spec/integration/server.rb +0 -51
- data/spec/savon/core_ext/net_http_spec.rb +0 -38
- data/spec/savon/core_ext/uri_spec.rb +0 -19
- data/spec/savon/request_spec.rb +0 -117
- data/spec/savon/response_spec.rb +0 -179
- data/spec/spec.opts +0 -4
@@ -1,16 +0,0 @@
|
|
1
|
-
require "basic_spec_helper"
|
2
|
-
|
3
|
-
describe Savon do
|
4
|
-
before { @client = Savon::Client.new "http://localhost:8080/http-basic-auth" }
|
5
|
-
|
6
|
-
it "should be able to handle HTTP basic authentication" do
|
7
|
-
@client.request.basic_auth "user", "password"
|
8
|
-
response = @client.do_something!
|
9
|
-
response.to_hash[:authenticate_response][:return][:success].should == true
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should raise a Savon::HTTPError in case authentication failed" do
|
13
|
-
lambda { @client.do_something! }.should raise_error(Savon::HTTPError)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
data/spec/integration/server.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require "webrick"
|
2
|
-
|
3
|
-
include WEBrick
|
4
|
-
|
5
|
-
# Run WEBrick. Yields the server to a given block.
|
6
|
-
def run_webrick(config = {})
|
7
|
-
config.update :Port => 8080
|
8
|
-
server = HTTPServer.new config
|
9
|
-
yield server if block_given?
|
10
|
-
["INT", "TERM"].each { |signal| trap(signal) { server.shutdown } }
|
11
|
-
server.start
|
12
|
-
end
|
13
|
-
|
14
|
-
# Returns the SOAP response fixture for a given +file+.
|
15
|
-
def respond_with(file)
|
16
|
-
response_path = File.dirname(__FILE__) + "/../fixtures/response/xml"
|
17
|
-
File.read "#{response_path}/#{file}.xml"
|
18
|
-
end
|
19
|
-
|
20
|
-
# Returns HTML links for a given Hash of link URI's and names.
|
21
|
-
def link_to(links)
|
22
|
-
links.map { |link| "<a href='#{link[:uri]}'>#{link[:name]}</a>" }.join("<br>")
|
23
|
-
end
|
24
|
-
|
25
|
-
run_webrick do |server|
|
26
|
-
user, password, realm = "user", "password", "realm"
|
27
|
-
|
28
|
-
htdigest = HTTPAuth::Htdigest.new "/tmp/webrick-htdigest"
|
29
|
-
htdigest.set_passwd realm, user, password
|
30
|
-
authenticator = HTTPAuth::DigestAuth.new :UserDB => htdigest, :Realm => realm
|
31
|
-
|
32
|
-
# Homepage including links to subpages.
|
33
|
-
server.mount_proc("/") do |request, response|
|
34
|
-
response.body = link_to [
|
35
|
-
{ :uri => "http-basic-auth", :name => "HTTP basic auth" },
|
36
|
-
{ :uri => "http-digest-auth", :name => "HTTP digest auth" }
|
37
|
-
]
|
38
|
-
end
|
39
|
-
|
40
|
-
# HTTP basic authentication.
|
41
|
-
server.mount_proc("/http-basic-auth") do |request, response|
|
42
|
-
HTTPAuth.basic_auth(request, response, realm) { |u, p| u == user && p == password }
|
43
|
-
response.body = respond_with :authentication
|
44
|
-
end
|
45
|
-
|
46
|
-
# HTTP digest authentication.
|
47
|
-
server.mount_proc("/http-digest-auth") do |request, response|
|
48
|
-
authenticator.authenticate request, response
|
49
|
-
response.body = "HTTP digest authentication successfull"
|
50
|
-
end
|
51
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Net::HTTP do
|
4
|
-
before do
|
5
|
-
@some_uri = URI "http://example.com"
|
6
|
-
@another_uri = URI "http://example.org"
|
7
|
-
@http = Net::HTTP.new @some_uri.host, @some_uri.port
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "endpoint" do
|
11
|
-
it "changes the address and port of a Net::HTTP object" do
|
12
|
-
@http.address.should == @some_uri.host
|
13
|
-
@http.port.should == @some_uri.port
|
14
|
-
|
15
|
-
@http.endpoint @another_uri.host, @another_uri.port
|
16
|
-
@http.address.should == @another_uri.host
|
17
|
-
@http.port.should == @another_uri.port
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "ssl_client_auth" do
|
22
|
-
it "accepts a Hash of options for SSL client authentication" do
|
23
|
-
@http.cert.should be_nil
|
24
|
-
@http.key.should be_nil
|
25
|
-
@http.ca_file.should be_nil
|
26
|
-
@http.verify_mode.should be_nil
|
27
|
-
|
28
|
-
@http.ssl_client_auth :cert => "cert", :key => "key",
|
29
|
-
:ca_file => "ca_file", :verify_mode => OpenSSL::SSL::VERIFY_PEER
|
30
|
-
|
31
|
-
@http.cert.should == "cert"
|
32
|
-
@http.key.should == "key"
|
33
|
-
@http.ca_file.should == "ca_file"
|
34
|
-
@http.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe URI::HTTP do
|
4
|
-
|
5
|
-
describe "ssl?" do
|
6
|
-
it "returns true for https URI's" do
|
7
|
-
URI("https://example.com").ssl?.should be_true
|
8
|
-
end
|
9
|
-
|
10
|
-
it "returns false for non-https URI's" do
|
11
|
-
URI("http://example.com").ssl?.should be_false
|
12
|
-
end
|
13
|
-
|
14
|
-
it "returns nil for invalid URI's without a scheme" do
|
15
|
-
URI("example").ssl?.should be_nil
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
data/spec/savon/request_spec.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Savon::Request do
|
4
|
-
before { @request = Savon::Request.new EndpointHelper.wsdl_endpoint }
|
5
|
-
|
6
|
-
it "contains the ContentType for each supported SOAP version" do
|
7
|
-
content_type = { 1 => "text/xml;charset=UTF-8", 2 => "application/soap+xml;charset=UTF-8" }
|
8
|
-
content_type.each { |version, type| Savon::Request::ContentType[version].should == type }
|
9
|
-
end
|
10
|
-
|
11
|
-
# defaults to log request and response. disabled for spec execution
|
12
|
-
|
13
|
-
it "has both getter and setter for whether to log (global setting)" do
|
14
|
-
Savon::Request.log = true
|
15
|
-
Savon::Request.log?.should be_true
|
16
|
-
Savon::Request.log = false
|
17
|
-
Savon::Request.log?.should be_false
|
18
|
-
end
|
19
|
-
|
20
|
-
it "defaults to use a Logger instance for logging" do
|
21
|
-
Savon::Request.logger.should be_a(Logger)
|
22
|
-
end
|
23
|
-
|
24
|
-
it "has both getter and setter for the logger to use (global setting)" do
|
25
|
-
Savon::Request.logger = {}
|
26
|
-
Savon::Request.logger.should be_a(Hash)
|
27
|
-
Savon::Request.logger = Logger.new STDOUT
|
28
|
-
end
|
29
|
-
|
30
|
-
it "defaults to :debug for logging" do
|
31
|
-
Savon::Request.log_level.should == :debug
|
32
|
-
end
|
33
|
-
|
34
|
-
it "has both getter and setter for the log level to use (global setting)" do
|
35
|
-
Savon::Request.log_level = :info
|
36
|
-
Savon::Request.log_level.should == :info
|
37
|
-
Savon::Request.log_level = :debug
|
38
|
-
end
|
39
|
-
|
40
|
-
it "is initialized with a SOAP endpoint String" do
|
41
|
-
Savon::Request.new EndpointHelper.wsdl_endpoint
|
42
|
-
end
|
43
|
-
|
44
|
-
it "has a getter for the SOAP endpoint URI" do
|
45
|
-
@request.endpoint.should == URI(EndpointHelper.wsdl_endpoint)
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should have a getter for the proxy URI" do
|
49
|
-
@request.proxy.should == URI("")
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should have a getter for the HTTP headers which defaults to an empty Hash" do
|
53
|
-
@request.headers.should == {}
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should have a setter for the HTTP headers" do
|
57
|
-
headers = { "some" => "thing" }
|
58
|
-
|
59
|
-
@request.headers = headers
|
60
|
-
@request.headers.should == headers
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should return the Net::HTTP object" do
|
64
|
-
@request.http.should be_kind_of(Net::HTTP)
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should have a method for setting HTTP basic auth credentials" do
|
68
|
-
@request.basic_auth "user", "password"
|
69
|
-
end
|
70
|
-
|
71
|
-
it "retrieves the WSDL document and returns the Net::HTTP response" do
|
72
|
-
wsdl_response = @request.wsdl
|
73
|
-
|
74
|
-
wsdl_response.should be_a(Net::HTTPResponse)
|
75
|
-
wsdl_response.body.should == WSDLFixture.authentication
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
describe "when executing a SOAP request" do
|
80
|
-
before :each do
|
81
|
-
operation = WSDLFixture.authentication(:operations)[:authenticate]
|
82
|
-
action, input = operation[:action], operation[:input]
|
83
|
-
@soap = Savon::SOAP.new action, input, EndpointHelper.soap_endpoint
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should return the Net::HTTP response" do
|
87
|
-
soap_response = @request.soap @soap
|
88
|
-
|
89
|
-
soap_response.should be_a(Net::HTTPResponse)
|
90
|
-
soap_response.body.should == ResponseFixture.authentication
|
91
|
-
end
|
92
|
-
|
93
|
-
it "should include Accept-Encoding gzip if it is enabled" do
|
94
|
-
@request = Savon::Request.new EndpointHelper.wsdl_endpoint, :gzip => true
|
95
|
-
a_post = Net::HTTP::Post.new(@soap.endpoint.request_uri, {})
|
96
|
-
|
97
|
-
Net::HTTP::Post.expects(:new).with(anything, has_entry("Accept-encoding" => "gzip,deflate")).returns(a_post)
|
98
|
-
|
99
|
-
@request.soap @soap
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should not include Accept-Encoding gzip if it is not enabled" do
|
103
|
-
@request = Savon::Request.new EndpointHelper.wsdl_endpoint, :gzip => false
|
104
|
-
a_post = Net::HTTP::Post.new(@soap.endpoint.request_uri, {})
|
105
|
-
|
106
|
-
Net::HTTP::Post.expects(:new).with(anything, Not(has_entry("Accept-encoding" => "gzip,deflate"))).returns(a_post)
|
107
|
-
|
108
|
-
@request.soap @soap
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should not include host when creating HTTP requests" do
|
113
|
-
request = @request.send(:request, :wsdl)
|
114
|
-
request.path.should_not include("example.com")
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
data/spec/savon/response_spec.rb
DELETED
@@ -1,179 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Savon::Response do
|
4
|
-
before { @response = Savon::Response.new http_response_mock }
|
5
|
-
|
6
|
-
it "defaults to raises both Savon::SOAPFault and Savon::HTTPError" do
|
7
|
-
Savon::Response.raise_errors?.should be_true
|
8
|
-
end
|
9
|
-
|
10
|
-
it "has both getter and setter for whether to raise errors (global setting)" do
|
11
|
-
Savon::Response.raise_errors = false
|
12
|
-
Savon::Response.raise_errors?.should == false
|
13
|
-
Savon::Response.raise_errors = true
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "initialize" do
|
17
|
-
it "expects a Net::HTTPResponse" do
|
18
|
-
Savon::Response.new http_response_mock
|
19
|
-
end
|
20
|
-
|
21
|
-
it "raises a Savon::SOAPFault in case of a SOAP fault" do
|
22
|
-
lambda { savon_response_with :soap_fault }.should raise_error(Savon::SOAPFault)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "does not raise a Savon::SOAPFault in case the default is turned off" do
|
26
|
-
Savon::Response.raise_errors = false
|
27
|
-
savon_response_with :soap_fault
|
28
|
-
Savon::Response.raise_errors = true
|
29
|
-
end
|
30
|
-
|
31
|
-
it "raises a Savon::HTTPError in case of an HTTP error" do
|
32
|
-
lambda { savon_response_with :http_error }.should raise_error(Savon::HTTPError)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "does not raise a Savon::HTTPError in case the default is turned off" do
|
36
|
-
Savon::Response.raise_errors = false
|
37
|
-
savon_response_with :http_error
|
38
|
-
Savon::Response.raise_errors = true
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "soap_fault?" do
|
43
|
-
before { Savon::Response.raise_errors = false }
|
44
|
-
|
45
|
-
it "does not return true in case the response seems to be ok" do
|
46
|
-
@response.soap_fault?.should_not be_true
|
47
|
-
end
|
48
|
-
|
49
|
-
it "returns true in case of a SOAP fault" do
|
50
|
-
savon_response_with(:soap_fault).soap_fault?.should be_true
|
51
|
-
end
|
52
|
-
|
53
|
-
after { Savon::Response.raise_errors = true }
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "soap_fault" do
|
57
|
-
before { Savon::Response.raise_errors = false }
|
58
|
-
|
59
|
-
it "returns the SOAP fault message in case of a SOAP fault" do
|
60
|
-
savon_response_with(:soap_fault).soap_fault.
|
61
|
-
should == "(soap:Server) Fault occurred while processing."
|
62
|
-
end
|
63
|
-
|
64
|
-
it "returns the SOAP fault message in case of a SOAP 1.2 fault" do
|
65
|
-
savon_response_with(:soap_fault12).soap_fault.
|
66
|
-
should == "(soap:Sender) Sender Timeout"
|
67
|
-
end
|
68
|
-
|
69
|
-
after { Savon::Response.raise_errors = true }
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "http_error?" do
|
73
|
-
before { Savon::Response.raise_errors = false }
|
74
|
-
|
75
|
-
it "does not return true in case the response seems to be ok" do
|
76
|
-
@response.http_error?.should_not be_true
|
77
|
-
end
|
78
|
-
|
79
|
-
it "returns true in case of an HTTP error" do
|
80
|
-
savon_response_with(:http_error).http_error?.should be_true
|
81
|
-
end
|
82
|
-
|
83
|
-
after { Savon::Response.raise_errors = true }
|
84
|
-
end
|
85
|
-
|
86
|
-
describe "http_error" do
|
87
|
-
before { Savon::Response.raise_errors = false }
|
88
|
-
|
89
|
-
it "returns the HTTP error message in case of an HTTP error" do
|
90
|
-
savon_response_with(:http_error).http_error.should == "Not found (404)"
|
91
|
-
end
|
92
|
-
|
93
|
-
after { Savon::Response.raise_errors = true }
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should return the SOAP response body as a Hash" do
|
97
|
-
@response.to_hash[:authenticate_response][:return].should ==
|
98
|
-
ResponseFixture.authentication(:to_hash)
|
99
|
-
end
|
100
|
-
|
101
|
-
it "should return a Hash for a SOAP multiRef response" do
|
102
|
-
@response = Savon::Response.new http_response_mock(200, ResponseFixture.multi_ref, "OK")
|
103
|
-
|
104
|
-
@response.to_hash[:list_response].should be_a(Hash)
|
105
|
-
@response.to_hash[:multi_ref].should be_an(Array)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should return the raw SOAP response body" do
|
109
|
-
@response.to_xml.should == ResponseFixture.authentication
|
110
|
-
@response.to_s.should == ResponseFixture.authentication
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should return the Net::HTTP response object" do
|
114
|
-
@response.http.should be_a(Mocha::Mock)
|
115
|
-
@response.http.should respond_to(:code)
|
116
|
-
@response.http.should respond_to(:message)
|
117
|
-
@response.http.should respond_to(:body)
|
118
|
-
end
|
119
|
-
|
120
|
-
describe "GZipped responses" do
|
121
|
-
it "should be decoded if Content-encoding header is gzip" do
|
122
|
-
@response = Savon::Response.new http_response_mock(200, body = "Encoded", "OK", 'content-encoding' => 'gzip')
|
123
|
-
|
124
|
-
should_decode_body body
|
125
|
-
|
126
|
-
@response.to_xml
|
127
|
-
end
|
128
|
-
|
129
|
-
# header logic extracted from http://dev.ctor.org/svn/soap4r/trunk/lib/soap/streamHandler.rb
|
130
|
-
it "should be decoded if body starts with gzip header" do
|
131
|
-
@response = Savon::Response.new http_response_mock(200, body = "\x1f\x8bEncoded", "OK")
|
132
|
-
|
133
|
-
should_decode_body body
|
134
|
-
|
135
|
-
@response.to_xml
|
136
|
-
end
|
137
|
-
|
138
|
-
it "should be decoded when header is set" do
|
139
|
-
@response = Savon::Response.new http_response_mock(200, GzipResponseFixture.message, "OK", 'content-encoding' => 'gzip')
|
140
|
-
@response.to_xml.should == "A short gzip encoded message\n"
|
141
|
-
end
|
142
|
-
|
143
|
-
it "should be decoded when header is not set" do
|
144
|
-
@response = Savon::Response.new http_response_mock(200, GzipResponseFixture.message, "OK")
|
145
|
-
@response.to_xml.should == "A short gzip encoded message\n"
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def should_decode_body(body)
|
150
|
-
StringIO.expects(:new).with(body).returns(stream = mock("StringIO"))
|
151
|
-
|
152
|
-
Zlib::GzipReader.expects(:new).with(stream).returns(mock("Zlib::GzipReader") do
|
153
|
-
expects(:read)
|
154
|
-
expects(:close)
|
155
|
-
end)
|
156
|
-
end
|
157
|
-
|
158
|
-
def savon_response_with(error_type)
|
159
|
-
mock = case error_type
|
160
|
-
when :soap_fault then http_response_mock 200, ResponseFixture.soap_fault
|
161
|
-
when :soap_fault12 then http_response_mock 200, ResponseFixture.soap_fault12
|
162
|
-
when :http_error then http_response_mock 404, "", "Not found"
|
163
|
-
end
|
164
|
-
Savon::Response.new mock
|
165
|
-
end
|
166
|
-
|
167
|
-
def http_response_mock(code = 200, body = nil, message = "OK", headers = {})
|
168
|
-
body ||= ResponseFixture.authentication
|
169
|
-
mock = mock "Net::HTTPResponse"
|
170
|
-
mock.stubs :code => code.to_s, :message => message, :content_type => "text/html", :body => body
|
171
|
-
|
172
|
-
mock.stubs("[]").with(anything).returns(nil)
|
173
|
-
headers.each { |key, value| mock.stubs("[]").with(key).returns(value) }
|
174
|
-
|
175
|
-
mock
|
176
|
-
end
|
177
|
-
|
178
|
-
end
|
179
|
-
|
data/spec/spec.opts
DELETED