http 0.7.4 → 0.8.0.pre

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +5 -2
  4. data/CHANGES.md +24 -7
  5. data/CONTRIBUTING.md +25 -0
  6. data/Gemfile +24 -22
  7. data/Guardfile +2 -2
  8. data/README.md +34 -4
  9. data/Rakefile +7 -7
  10. data/examples/parallel_requests_with_celluloid.rb +2 -2
  11. data/http.gemspec +12 -12
  12. data/lib/http.rb +11 -10
  13. data/lib/http/cache.rb +146 -0
  14. data/lib/http/cache/headers.rb +100 -0
  15. data/lib/http/cache/null_cache.rb +13 -0
  16. data/lib/http/chainable.rb +14 -3
  17. data/lib/http/client.rb +64 -80
  18. data/lib/http/connection.rb +139 -0
  19. data/lib/http/content_type.rb +2 -2
  20. data/lib/http/errors.rb +7 -1
  21. data/lib/http/headers.rb +21 -8
  22. data/lib/http/headers/mixin.rb +1 -1
  23. data/lib/http/mime_type.rb +2 -2
  24. data/lib/http/mime_type/adapter.rb +2 -2
  25. data/lib/http/mime_type/json.rb +4 -4
  26. data/lib/http/options.rb +65 -74
  27. data/lib/http/redirector.rb +3 -3
  28. data/lib/http/request.rb +20 -13
  29. data/lib/http/request/caching.rb +95 -0
  30. data/lib/http/request/writer.rb +5 -5
  31. data/lib/http/response.rb +15 -9
  32. data/lib/http/response/body.rb +21 -8
  33. data/lib/http/response/caching.rb +142 -0
  34. data/lib/http/response/io_body.rb +63 -0
  35. data/lib/http/response/parser.rb +1 -1
  36. data/lib/http/response/status.rb +4 -12
  37. data/lib/http/response/status/reasons.rb +53 -53
  38. data/lib/http/response/string_body.rb +53 -0
  39. data/lib/http/version.rb +1 -1
  40. data/spec/lib/http/cache/headers_spec.rb +77 -0
  41. data/spec/lib/http/cache_spec.rb +182 -0
  42. data/spec/lib/http/client_spec.rb +123 -95
  43. data/spec/lib/http/content_type_spec.rb +25 -25
  44. data/spec/lib/http/headers/mixin_spec.rb +8 -8
  45. data/spec/lib/http/headers_spec.rb +213 -173
  46. data/spec/lib/http/options/body_spec.rb +5 -5
  47. data/spec/lib/http/options/form_spec.rb +3 -3
  48. data/spec/lib/http/options/headers_spec.rb +7 -7
  49. data/spec/lib/http/options/json_spec.rb +3 -3
  50. data/spec/lib/http/options/merge_spec.rb +26 -22
  51. data/spec/lib/http/options/new_spec.rb +10 -10
  52. data/spec/lib/http/options/proxy_spec.rb +8 -8
  53. data/spec/lib/http/options_spec.rb +2 -2
  54. data/spec/lib/http/redirector_spec.rb +32 -32
  55. data/spec/lib/http/request/caching_spec.rb +133 -0
  56. data/spec/lib/http/request/writer_spec.rb +26 -26
  57. data/spec/lib/http/request_spec.rb +63 -58
  58. data/spec/lib/http/response/body_spec.rb +13 -13
  59. data/spec/lib/http/response/caching_spec.rb +201 -0
  60. data/spec/lib/http/response/io_body_spec.rb +35 -0
  61. data/spec/lib/http/response/status_spec.rb +25 -25
  62. data/spec/lib/http/response/string_body_spec.rb +35 -0
  63. data/spec/lib/http/response_spec.rb +64 -45
  64. data/spec/lib/http_spec.rb +103 -76
  65. data/spec/spec_helper.rb +10 -12
  66. data/spec/support/connection_reuse_shared.rb +100 -0
  67. data/spec/support/create_certs.rb +12 -12
  68. data/spec/support/dummy_server.rb +11 -11
  69. data/spec/support/dummy_server/servlet.rb +43 -31
  70. data/spec/support/proxy_server.rb +31 -25
  71. metadata +57 -8
  72. data/spec/support/example_server.rb +0 -30
  73. data/spec/support/example_server/servlet.rb +0 -102
@@ -1,13 +1,13 @@
1
- RSpec.describe HTTP::Options, 'body' do
1
+ RSpec.describe HTTP::Options, "body" do
2
2
  let(:opts) { HTTP::Options.new }
3
3
 
4
- it 'defaults to nil' do
4
+ it "defaults to nil" do
5
5
  expect(opts.body).to be nil
6
6
  end
7
7
 
8
- it 'may be specified with with_body' do
9
- opts2 = opts.with_body('foo')
8
+ it "may be specified with with_body" do
9
+ opts2 = opts.with_body("foo")
10
10
  expect(opts.body).to be nil
11
- expect(opts2.body).to eq('foo')
11
+ expect(opts2.body).to eq("foo")
12
12
  end
13
13
  end
@@ -1,11 +1,11 @@
1
- RSpec.describe HTTP::Options, 'form' do
1
+ RSpec.describe HTTP::Options, "form" do
2
2
  let(:opts) { HTTP::Options.new }
3
3
 
4
- it 'defaults to nil' do
4
+ it "defaults to nil" do
5
5
  expect(opts.form).to be nil
6
6
  end
7
7
 
8
- it 'may be specified with with_form_data' do
8
+ it "may be specified with with_form_data" do
9
9
  opts2 = opts.with_form(:foo => 42)
10
10
  expect(opts.form).to be nil
11
11
  expect(opts2.form).to eq(:foo => 42)
@@ -1,18 +1,18 @@
1
- RSpec.describe HTTP::Options, 'headers' do
1
+ RSpec.describe HTTP::Options, "headers" do
2
2
  let(:opts) { HTTP::Options.new }
3
3
 
4
- it 'defaults to be empty' do
4
+ it "defaults to be empty" do
5
5
  expect(opts.headers).to be_empty
6
6
  end
7
7
 
8
- it 'may be specified with with_headers' do
9
- opts2 = opts.with_headers('accept' => 'json')
8
+ it "may be specified with with_headers" do
9
+ opts2 = opts.with_headers("accept" => "json")
10
10
  expect(opts.headers).to be_empty
11
11
  expect(opts2.headers).to eq([%w(Accept json)])
12
12
  end
13
13
 
14
- it 'accepts any object that respond to :to_hash' do
15
- x = Struct.new(:to_hash).new('accept' => 'json')
16
- expect(opts.with_headers(x).headers['accept']).to eq('json')
14
+ it "accepts any object that respond to :to_hash" do
15
+ x = Struct.new(:to_hash).new("accept" => "json")
16
+ expect(opts.with_headers(x).headers["accept"]).to eq("json")
17
17
  end
18
18
  end
@@ -1,11 +1,11 @@
1
- RSpec.describe HTTP::Options, 'json' do
1
+ RSpec.describe HTTP::Options, "json" do
2
2
  let(:opts) { HTTP::Options.new }
3
3
 
4
- it 'defaults to nil' do
4
+ it "defaults to nil" do
5
5
  expect(opts.json).to be nil
6
6
  end
7
7
 
8
- it 'may be specified with with_json data' do
8
+ it "may be specified with with_json data" do
9
9
  opts2 = opts.with_json(:foo => 42)
10
10
  expect(opts.json).to be nil
11
11
  expect(opts2.json).to eq(:foo => 42)
@@ -1,49 +1,53 @@
1
- RSpec.describe HTTP::Options, 'merge' do
1
+
2
+ RSpec.describe HTTP::Options, "merge" do
2
3
  let(:opts) { HTTP::Options.new }
3
4
 
4
- it 'supports a Hash' do
5
+ it "supports a Hash" do
5
6
  old_response = opts.response
6
7
  expect(opts.merge(:response => :body).response).to eq(:body)
7
8
  expect(opts.response).to eq(old_response)
8
9
  end
9
10
 
10
- it 'supports another Options' do
11
+ it "supports another Options" do
11
12
  merged = opts.merge(HTTP::Options.new(:response => :body))
12
13
  expect(merged.response).to eq(:body)
13
14
  end
14
15
 
15
- it 'merges as excepted in complex cases' do
16
+ it "merges as excepted in complex cases" do
16
17
  # FIXME: yuck :(
17
18
 
18
19
  foo = HTTP::Options.new(
19
20
  :response => :body,
20
- :params => {:baz => 'bar'},
21
- :form => {:foo => 'foo'},
22
- :body => 'body-foo',
23
- :json => {:foo => 'foo'},
24
- :headers => {:accept => 'json', :foo => 'foo'},
21
+ :params => {:baz => "bar"},
22
+ :form => {:foo => "foo"},
23
+ :body => "body-foo",
24
+ :json => {:foo => "foo"},
25
+ :headers => {:accept => "json", :foo => "foo"},
25
26
  :proxy => {})
26
27
 
27
28
  bar = HTTP::Options.new(
28
29
  :response => :parsed_body,
29
- :params => {:plop => 'plip'},
30
- :form => {:bar => 'bar'},
31
- :body => 'body-bar',
32
- :json => {:bar => 'bar'},
33
- :headers => {:accept => 'xml', :bar => 'bar'},
34
- :proxy => {:proxy_address => '127.0.0.1', :proxy_port => 8080})
30
+ :persistent => "https://www.googe.com",
31
+ :params => {:plop => "plip"},
32
+ :form => {:bar => "bar"},
33
+ :body => "body-bar",
34
+ :json => {:bar => "bar"},
35
+ :headers => {:accept => "xml", :bar => "bar"},
36
+ :proxy => {:proxy_address => "127.0.0.1", :proxy_port => 8080})
35
37
 
36
38
  expect(foo.merge(bar).to_hash).to eq(
37
39
  :response => :parsed_body,
38
- :params => {:plop => 'plip'},
39
- :form => {:bar => 'bar'},
40
- :body => 'body-bar',
41
- :json => {:bar => 'bar'},
42
- :headers => {'Accept' => 'xml', 'Foo' => 'foo', 'Bar' => 'bar'},
43
- :proxy => {:proxy_address => '127.0.0.1', :proxy_port => 8080},
40
+ :params => {:plop => "plip"},
41
+ :form => {:bar => "bar"},
42
+ :body => "body-bar",
43
+ :json => {:bar => "bar"},
44
+ :persistent => "https://www.googe.com",
45
+ :headers => {"Foo" => "foo", "Accept" => "xml", "Bar" => "bar"},
46
+ :proxy => {:proxy_address => "127.0.0.1", :proxy_port => 8080},
44
47
  :follow => nil,
45
48
  :socket_class => described_class.default_socket_class,
46
49
  :ssl_socket_class => described_class.default_ssl_socket_class,
47
- :ssl_context => nil)
50
+ :ssl_context => nil,
51
+ :cache => described_class.default_cache)
48
52
  end
49
53
  end
@@ -1,26 +1,26 @@
1
- RSpec.describe HTTP::Options, 'new' do
2
- it 'supports a Options instance' do
1
+ RSpec.describe HTTP::Options, "new" do
2
+ it "supports a Options instance" do
3
3
  opts = HTTP::Options.new
4
4
  expect(HTTP::Options.new(opts)).to eq(opts)
5
5
  end
6
6
 
7
- context 'with a Hash' do
8
- it 'coerces :response correctly' do
7
+ context "with a Hash" do
8
+ it "coerces :response correctly" do
9
9
  opts = HTTP::Options.new(:response => :object)
10
10
  expect(opts.response).to eq(:object)
11
11
  end
12
12
 
13
- it 'coerces :headers correctly' do
14
- opts = HTTP::Options.new(:headers => {:accept => 'json'})
13
+ it "coerces :headers correctly" do
14
+ opts = HTTP::Options.new(:headers => {:accept => "json"})
15
15
  expect(opts.headers).to eq([%w(Accept json)])
16
16
  end
17
17
 
18
- it 'coerces :proxy correctly' do
19
- opts = HTTP::Options.new(:proxy => {:proxy_address => '127.0.0.1', :proxy_port => 8080})
20
- expect(opts.proxy).to eq(:proxy_address => '127.0.0.1', :proxy_port => 8080)
18
+ it "coerces :proxy correctly" do
19
+ opts = HTTP::Options.new(:proxy => {:proxy_address => "127.0.0.1", :proxy_port => 8080})
20
+ expect(opts.proxy).to eq(:proxy_address => "127.0.0.1", :proxy_port => 8080)
21
21
  end
22
22
 
23
- it 'coerces :form correctly' do
23
+ it "coerces :form correctly" do
24
24
  opts = HTTP::Options.new(:form => {:foo => 42})
25
25
  expect(opts.form).to eq(:foo => 42)
26
26
  end
@@ -1,18 +1,18 @@
1
- RSpec.describe HTTP::Options, 'proxy' do
1
+ RSpec.describe HTTP::Options, "proxy" do
2
2
  let(:opts) { HTTP::Options.new }
3
3
 
4
- it 'defaults to {}' do
4
+ it "defaults to {}" do
5
5
  expect(opts.proxy).to eq({})
6
6
  end
7
7
 
8
- it 'may be specified with with_proxy' do
9
- opts2 = opts.with_proxy(:proxy_address => '127.0.0.1', :proxy_port => 8080)
8
+ it "may be specified with with_proxy" do
9
+ opts2 = opts.with_proxy(:proxy_address => "127.0.0.1", :proxy_port => 8080)
10
10
  expect(opts.proxy).to eq({})
11
- expect(opts2.proxy).to eq(:proxy_address => '127.0.0.1', :proxy_port => 8080)
11
+ expect(opts2.proxy).to eq(:proxy_address => "127.0.0.1", :proxy_port => 8080)
12
12
  end
13
13
 
14
- it 'accepts proxy address, port, username, and password' do
15
- opts2 = opts.with_proxy(:proxy_address => '127.0.0.1', :proxy_port => 8080, :proxy_username => 'username', :proxy_password => 'password')
16
- expect(opts2.proxy).to eq(:proxy_address => '127.0.0.1', :proxy_port => 8080, :proxy_username => 'username', :proxy_password => 'password')
14
+ it "accepts proxy address, port, username, and password" do
15
+ opts2 = opts.with_proxy(:proxy_address => "127.0.0.1", :proxy_port => 8080, :proxy_username => "username", :proxy_password => "password")
16
+ expect(opts2.proxy).to eq(:proxy_address => "127.0.0.1", :proxy_port => 8080, :proxy_username => "username", :proxy_password => "password")
17
17
  end
18
18
  end
@@ -1,12 +1,12 @@
1
1
  RSpec.describe HTTP::Options do
2
2
  subject { described_class.new(:response => :body) }
3
3
 
4
- it 'behaves like a Hash for reading' do
4
+ it "behaves like a Hash for reading" do
5
5
  expect(subject[:response]).to eq(:body)
6
6
  expect(subject[:nosuchone]).to be nil
7
7
  end
8
8
 
9
- it 'coerces to a Hash' do
9
+ it "coerces to a Hash" do
10
10
  expect(subject.to_hash).to be_a(Hash)
11
11
  end
12
12
  end
@@ -1,20 +1,20 @@
1
1
  RSpec.describe HTTP::Redirector do
2
- def simple_response(status, body = '', headers = {})
3
- HTTP::Response.new(status, '1.1', headers, body)
2
+ def simple_response(status, body = "", headers = {})
3
+ HTTP::Response.new(status, "1.1", headers, body)
4
4
  end
5
5
 
6
6
  def redirect_response(location, status)
7
- simple_response status, '', 'Location' => location
7
+ simple_response status, "", "Location" => location
8
8
  end
9
9
 
10
10
  let(:max_hops) { 5 }
11
11
  subject(:redirector) { described_class.new max_hops }
12
12
 
13
- context 'following 300 redirect' do
14
- let(:orig_request) { HTTP::Request.new :post, 'http://www.example.com/' }
15
- let(:orig_response) { redirect_response 'http://example.com/', 300 }
13
+ context "following 300 redirect" do
14
+ let(:orig_request) { HTTP::Request.new :post, "http://www.example.com/" }
15
+ let(:orig_response) { redirect_response "http://example.com/", 300 }
16
16
 
17
- it 'follows without changing verb' do
17
+ it "follows without changing verb" do
18
18
  redirector.perform(orig_request, orig_response) do |request|
19
19
  expect(request.verb).to be orig_request.verb
20
20
  simple_response 200
@@ -22,11 +22,11 @@ RSpec.describe HTTP::Redirector do
22
22
  end
23
23
  end
24
24
 
25
- context 'following 301 redirect' do
26
- let(:orig_request) { HTTP::Request.new :post, 'http://www.example.com/' }
27
- let(:orig_response) { redirect_response 'http://example.com/', 301 }
25
+ context "following 301 redirect" do
26
+ let(:orig_request) { HTTP::Request.new :post, "http://www.example.com/" }
27
+ let(:orig_response) { redirect_response "http://example.com/", 301 }
28
28
 
29
- it 'follows without changing verb' do
29
+ it "follows without changing verb" do
30
30
  redirector.perform(orig_request, orig_response) do |request|
31
31
  expect(request.verb).to be orig_request.verb
32
32
  simple_response 200
@@ -34,11 +34,11 @@ RSpec.describe HTTP::Redirector do
34
34
  end
35
35
  end
36
36
 
37
- context 'following 302 redirect' do
38
- let(:orig_request) { HTTP::Request.new :post, 'http://www.example.com/' }
39
- let(:orig_response) { redirect_response 'http://example.com/', 302 }
37
+ context "following 302 redirect" do
38
+ let(:orig_request) { HTTP::Request.new :post, "http://www.example.com/" }
39
+ let(:orig_response) { redirect_response "http://example.com/", 302 }
40
40
 
41
- it 'follows without changing verb' do
41
+ it "follows without changing verb" do
42
42
  redirector.perform(orig_request, orig_response) do |request|
43
43
  expect(request.verb).to be orig_request.verb
44
44
  simple_response 200
@@ -46,12 +46,12 @@ RSpec.describe HTTP::Redirector do
46
46
  end
47
47
  end
48
48
 
49
- context 'following 303 redirect' do
50
- context 'upon POST request' do
51
- let(:orig_request) { HTTP::Request.new :post, 'http://www.example.com/' }
52
- let(:orig_response) { redirect_response 'http://example.com/', 303 }
49
+ context "following 303 redirect" do
50
+ context "upon POST request" do
51
+ let(:orig_request) { HTTP::Request.new :post, "http://www.example.com/" }
52
+ let(:orig_response) { redirect_response "http://example.com/", 303 }
53
53
 
54
- it 'follows without changing verb' do
54
+ it "follows without changing verb" do
55
55
  redirector.perform(orig_request, orig_response) do |request|
56
56
  expect(request.verb).to be :get
57
57
  simple_response 200
@@ -59,11 +59,11 @@ RSpec.describe HTTP::Redirector do
59
59
  end
60
60
  end
61
61
 
62
- context 'upon HEAD request' do
63
- let(:orig_request) { HTTP::Request.new :head, 'http://www.example.com/' }
64
- let(:orig_response) { redirect_response 'http://example.com/', 303 }
62
+ context "upon HEAD request" do
63
+ let(:orig_request) { HTTP::Request.new :head, "http://www.example.com/" }
64
+ let(:orig_response) { redirect_response "http://example.com/", 303 }
65
65
 
66
- it 'follows without changing verb' do
66
+ it "follows without changing verb" do
67
67
  redirector.perform(orig_request, orig_response) do |request|
68
68
  expect(request.verb).to be :get
69
69
  simple_response 200
@@ -72,11 +72,11 @@ RSpec.describe HTTP::Redirector do
72
72
  end
73
73
  end
74
74
 
75
- context 'following 307 redirect' do
76
- let(:orig_request) { HTTP::Request.new :post, 'http://www.example.com/' }
77
- let(:orig_response) { redirect_response 'http://example.com/', 307 }
75
+ context "following 307 redirect" do
76
+ let(:orig_request) { HTTP::Request.new :post, "http://www.example.com/" }
77
+ let(:orig_response) { redirect_response "http://example.com/", 307 }
78
78
 
79
- it 'follows without changing verb' do
79
+ it "follows without changing verb" do
80
80
  redirector.perform(orig_request, orig_response) do |request|
81
81
  expect(request.verb).to be orig_request.verb
82
82
  simple_response 200
@@ -84,11 +84,11 @@ RSpec.describe HTTP::Redirector do
84
84
  end
85
85
  end
86
86
 
87
- context 'following 308 redirect' do
88
- let(:orig_request) { HTTP::Request.new :post, 'http://www.example.com/' }
89
- let(:orig_response) { redirect_response 'http://example.com/', 308 }
87
+ context "following 308 redirect" do
88
+ let(:orig_request) { HTTP::Request.new :post, "http://www.example.com/" }
89
+ let(:orig_response) { redirect_response "http://example.com/", 308 }
90
90
 
91
- it 'follows without changing verb' do
91
+ it "follows without changing verb" do
92
92
  redirector.perform(orig_request, orig_response) do |request|
93
93
  expect(request.verb).to be orig_request.verb
94
94
  simple_response 200
@@ -0,0 +1,133 @@
1
+ RSpec.describe HTTP::Request::Caching do
2
+ let(:request) { HTTP::Request.new(:get, "http://example.com/") }
3
+
4
+ subject(:caching_request) { described_class.new request }
5
+
6
+ describe "#cache_headers" do
7
+ subject { caching_request.cache_headers }
8
+ it { is_expected.to be_a HTTP::Cache::Headers }
9
+ end
10
+
11
+ context "basic GET request" do
12
+ it "is cacheable" do
13
+ expect(subject.cacheable?).to be_truthy
14
+ end
15
+
16
+ it "does not invalidate cache" do
17
+ expect(subject.invalidates_cache?).to be_falsy
18
+ end
19
+
20
+ it "does not skip cache" do
21
+ expect(subject.skips_cache?).to be_falsy
22
+ end
23
+
24
+ it "can construct a new conditional version of itself based on a caching response" do
25
+ mod_date = Time.now.httpdate
26
+ headers = {"Etag" => "foo", "Last-Modified" => mod_date}
27
+ cached_resp = HTTP::Response.new(200, "http/1.1", headers, "")
28
+ cond_req = subject.conditional_on_changes_to(cached_resp)
29
+
30
+ expect(cond_req.headers["If-None-Match"]).to eq "foo"
31
+ expect(cond_req.headers["If-Modified-Since"]).to eq mod_date
32
+ end
33
+ end
34
+
35
+ context "GET request w/ must-revalidate" do
36
+ let(:request) do
37
+ headers = {"cache-control" => "must-revalidate"}
38
+ HTTP::Request.new(:get, "http://example.com/", headers)
39
+ end
40
+
41
+ it "is cacheable" do
42
+ expect(subject.cacheable?).to be_truthy
43
+ end
44
+
45
+ it "does not invalidate cache" do
46
+ expect(subject.invalidates_cache?).to be_falsy
47
+ end
48
+
49
+ it "does not skip cache" do
50
+ expect(subject.skips_cache?).to be_truthy
51
+ end
52
+
53
+ it "can construct a condition version of itself based on a caching response" do
54
+ mod_date = Time.now.httpdate
55
+ headers = {"Etag" => "foo", "Last-Modified" => mod_date}
56
+ cached_resp = HTTP::Response.new(200, "http/1.1", headers, "")
57
+ cond_req = subject.conditional_on_changes_to(cached_resp)
58
+
59
+ expect(cond_req.headers["If-None-Match"]).to eq "foo"
60
+ expect(cond_req.headers["If-Modified-Since"]).to eq mod_date
61
+ expect(cond_req.cache_headers.max_age).to eq 0
62
+ end
63
+ end
64
+
65
+ context "basic POST request" do
66
+ let(:request) { HTTP::Request.new(:post, "http://example.com/") }
67
+
68
+ it "is cacheable" do
69
+ expect(subject.cacheable?).to be_falsy
70
+ end
71
+
72
+ it "does not invalidate cache" do
73
+ expect(subject.invalidates_cache?).to be_truthy
74
+ end
75
+
76
+ it "does not skip cache" do
77
+ expect(subject.skips_cache?).to be_falsy
78
+ end
79
+ end
80
+
81
+ context "basic PUT request" do
82
+ let(:request) { HTTP::Request.new(:put, "http://example.com/") }
83
+
84
+ it "is cacheable" do
85
+ expect(subject.cacheable?).to be_falsy
86
+ end
87
+
88
+ it "does not invalidate cache" do
89
+ expect(subject.invalidates_cache?).to be_truthy
90
+ end
91
+
92
+ it "does not skip cache" do
93
+ expect(subject.skips_cache?).to be_falsy
94
+ end
95
+ end
96
+
97
+ context "basic delete request" do
98
+ let(:request) { HTTP::Request.new(:delete, "http://example.com/") }
99
+
100
+ it "is cacheable" do
101
+ expect(subject.cacheable?).to be_falsy
102
+ end
103
+
104
+ it "does not invalidate cache" do
105
+ expect(subject.invalidates_cache?).to be_truthy
106
+ end
107
+
108
+ it "does not skip cache" do
109
+ expect(subject.skips_cache?).to be_falsy
110
+ end
111
+ end
112
+
113
+ context "basic patch request" do
114
+ let(:request) { HTTP::Request.new(:patch, "http://example.com/") }
115
+
116
+ it "is cacheable" do
117
+ expect(subject.cacheable?).to be_falsy
118
+ end
119
+
120
+ it "does not invalidate cache" do
121
+ expect(subject.invalidates_cache?).to be_truthy
122
+ end
123
+
124
+ it "does not skip cache" do
125
+ expect(subject.skips_cache?).to be_falsy
126
+ end
127
+ end
128
+
129
+ describe "#caching" do
130
+ subject(:caching_request) { request.caching }
131
+ it { is_expected.to be caching_request }
132
+ end
133
+ end