htty 1.0.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.
Files changed (90) hide show
  1. data/MIT-LICENSE.rdoc +9 -0
  2. data/README.rdoc +199 -0
  3. data/VERSION +1 -0
  4. data/app/htty.rb +14 -0
  5. data/app/htty/cli.rb +77 -0
  6. data/app/htty/cli/command.rb +185 -0
  7. data/app/htty/cli/commands.rb +43 -0
  8. data/app/htty/cli/commands/address.rb +84 -0
  9. data/app/htty/cli/commands/body_clear.rb +20 -0
  10. data/app/htty/cli/commands/body_request.rb +51 -0
  11. data/app/htty/cli/commands/body_response.rb +59 -0
  12. data/app/htty/cli/commands/body_set.rb +58 -0
  13. data/app/htty/cli/commands/body_unset.rb +45 -0
  14. data/app/htty/cli/commands/cd.rb +20 -0
  15. data/app/htty/cli/commands/cookie_add.rb +20 -0
  16. data/app/htty/cli/commands/cookie_remove.rb +20 -0
  17. data/app/htty/cli/commands/cookies.rb +68 -0
  18. data/app/htty/cli/commands/cookies_add.rb +62 -0
  19. data/app/htty/cli/commands/cookies_clear.rb +20 -0
  20. data/app/htty/cli/commands/cookies_remove.rb +60 -0
  21. data/app/htty/cli/commands/cookies_remove_all.rb +50 -0
  22. data/app/htty/cli/commands/cookies_use.rb +57 -0
  23. data/app/htty/cli/commands/delete.rb +20 -0
  24. data/app/htty/cli/commands/exit.rb +20 -0
  25. data/app/htty/cli/commands/follow.rb +56 -0
  26. data/app/htty/cli/commands/form.rb +20 -0
  27. data/app/htty/cli/commands/form_add.rb +20 -0
  28. data/app/htty/cli/commands/form_clear.rb +26 -0
  29. data/app/htty/cli/commands/form_remove.rb +20 -0
  30. data/app/htty/cli/commands/form_remove_all.rb +20 -0
  31. data/app/htty/cli/commands/fragment_clear.rb +20 -0
  32. data/app/htty/cli/commands/fragment_set.rb +59 -0
  33. data/app/htty/cli/commands/fragment_unset.rb +48 -0
  34. data/app/htty/cli/commands/get.rb +20 -0
  35. data/app/htty/cli/commands/header_set.rb +20 -0
  36. data/app/htty/cli/commands/header_unset.rb +20 -0
  37. data/app/htty/cli/commands/headers_clear.rb +20 -0
  38. data/app/htty/cli/commands/headers_request.rb +70 -0
  39. data/app/htty/cli/commands/headers_response.rb +65 -0
  40. data/app/htty/cli/commands/headers_set.rb +57 -0
  41. data/app/htty/cli/commands/headers_unset.rb +54 -0
  42. data/app/htty/cli/commands/headers_unset_all.rb +48 -0
  43. data/app/htty/cli/commands/help.rb +100 -0
  44. data/app/htty/cli/commands/history.rb +60 -0
  45. data/app/htty/cli/commands/history_verbose.rb +81 -0
  46. data/app/htty/cli/commands/host_set.rb +59 -0
  47. data/app/htty/cli/commands/http_delete.rb +40 -0
  48. data/app/htty/cli/commands/http_get.rb +42 -0
  49. data/app/htty/cli/commands/http_head.rb +36 -0
  50. data/app/htty/cli/commands/http_options.rb +36 -0
  51. data/app/htty/cli/commands/http_post.rb +34 -0
  52. data/app/htty/cli/commands/http_put.rb +29 -0
  53. data/app/htty/cli/commands/http_trace.rb +36 -0
  54. data/app/htty/cli/commands/path_set.rb +54 -0
  55. data/app/htty/cli/commands/port_set.rb +55 -0
  56. data/app/htty/cli/commands/post.rb +20 -0
  57. data/app/htty/cli/commands/put.rb +20 -0
  58. data/app/htty/cli/commands/query_clear.rb +20 -0
  59. data/app/htty/cli/commands/query_set.rb +59 -0
  60. data/app/htty/cli/commands/query_unset.rb +56 -0
  61. data/app/htty/cli/commands/query_unset_all.rb +50 -0
  62. data/app/htty/cli/commands/quit.rb +24 -0
  63. data/app/htty/cli/commands/reuse.rb +74 -0
  64. data/app/htty/cli/commands/scheme_set.rb +69 -0
  65. data/app/htty/cli/commands/status.rb +52 -0
  66. data/app/htty/cli/commands/undo.rb +13 -0
  67. data/app/htty/cli/commands/userinfo_clear.rb +20 -0
  68. data/app/htty/cli/commands/userinfo_set.rb +56 -0
  69. data/app/htty/cli/commands/userinfo_unset.rb +47 -0
  70. data/app/htty/cli/cookie_clearing_command.rb +26 -0
  71. data/app/htty/cli/display.rb +182 -0
  72. data/app/htty/cli/http_method_command.rb +75 -0
  73. data/app/htty/cli/url_escaping.rb +27 -0
  74. data/app/htty/cookies_util.rb +36 -0
  75. data/app/htty/no_location_header_error.rb +12 -0
  76. data/app/htty/no_response_error.rb +12 -0
  77. data/app/htty/no_set_cookie_header_error.rb +13 -0
  78. data/app/htty/ordered_hash.rb +69 -0
  79. data/app/htty/payload.rb +48 -0
  80. data/app/htty/request.rb +471 -0
  81. data/app/htty/requests_util.rb +92 -0
  82. data/app/htty/response.rb +34 -0
  83. data/app/htty/session.rb +29 -0
  84. data/bin/htty +5 -0
  85. data/spec/unit/htty/cli_spec.rb +27 -0
  86. data/spec/unit/htty/ordered_hash_spec.rb +54 -0
  87. data/spec/unit/htty/request_spec.rb +1236 -0
  88. data/spec/unit/htty/response_spec.rb +0 -0
  89. data/spec/unit/htty/session_spec.rb +13 -0
  90. metadata +158 -0
@@ -0,0 +1,92 @@
1
+ # Defines HTTY::RequestsUtil.
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require File.expand_path("#{File.dirname __FILE__}/response")
6
+
7
+ module HTTY; end
8
+
9
+ # Provides support for making HTTP(S) requests.
10
+ module HTTY::RequestsUtil
11
+
12
+ # Makes an HTTP DELETE request with the specified _request_.
13
+ def self.delete(request)
14
+ request(request) do |host|
15
+ host.delete request.send(:path_query_and_fragment), request.headers
16
+ end
17
+ end
18
+
19
+ # Makes an HTTP GET request with the specified _request_.
20
+ def self.get(request)
21
+ request(request) do |host|
22
+ host.request_get request.send(:path_query_and_fragment), request.headers
23
+ end
24
+ end
25
+
26
+ # Makes an HTTP HEAD request with the specified _request_.
27
+ def self.head(request)
28
+ request(request) do |host|
29
+ host.head request.send(:path_query_and_fragment), request.headers
30
+ end
31
+ end
32
+
33
+ # Makes an HTTP OPTIONS request with the specified _request_.
34
+ def self.options(request)
35
+ request(request) do |host|
36
+ host.options request.send(:path_query_and_fragment), request.headers
37
+ end
38
+ end
39
+
40
+ # Makes an HTTP POST request with the specified _request_.
41
+ def self.post(request)
42
+ request(request) do |host|
43
+ host.post request.send(:path_query_and_fragment),
44
+ request.body,
45
+ request.headers
46
+ end
47
+ end
48
+
49
+ # Makes an HTTP PUT request with the specified _request_.
50
+ def self.put(request)
51
+ request(request) do |host|
52
+ host.put request.send(:path_query_and_fragment),
53
+ request.body,
54
+ request.headers
55
+ end
56
+ end
57
+
58
+ # Makes an HTTP TRACE request with the specified _request_.
59
+ def self.trace(request)
60
+ request(request) do |host|
61
+ host.trace request.send(:path_query_and_fragment), request.headers
62
+ end
63
+ end
64
+
65
+ protected
66
+
67
+ def self.http_response_to_status(http_response)
68
+ [http_response.code,
69
+ http_response.code_type.name.gsub(/^Net::HTTP/, '').
70
+ gsub(/(\S)([A-Z][a-z])/, '\1 \2')]
71
+ end
72
+
73
+ private
74
+
75
+ def self.request(request)
76
+ http = Net::HTTP.new(request.uri.host, request.uri.port)
77
+ http.use_ssl = true if (request.uri === URI::HTTPS)
78
+ http.start do |host|
79
+ http_response = yield(host)
80
+ headers = []
81
+ http_response.canonical_each do |*h|
82
+ headers << h
83
+ end
84
+ request.send :response=,
85
+ HTTY::Response.new(:status => http_response_to_status(http_response),
86
+ :headers => headers,
87
+ :body => http_response.body)
88
+ end
89
+ request
90
+ end
91
+
92
+ end
@@ -0,0 +1,34 @@
1
+ # Defines HTTY::Response.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/cookies_util")
4
+ require File.expand_path("#{File.dirname __FILE__}/payload")
5
+
6
+ module HTTY; end
7
+
8
+ # Encapsulates an HTTP(S) response.
9
+ class HTTY::Response < HTTY::Payload
10
+
11
+ COOKIES_HEADER_NAME = 'Set-Cookie'
12
+
13
+ # Returns the HTTP status associated with the response.
14
+ attr_reader :status
15
+
16
+ # Initializes a new HTTY::Response with attribute values specified in the
17
+ # _attributes_ hash.
18
+ #
19
+ # Valid _attributes_ keys include:
20
+ #
21
+ # * <tt>:body</tt>
22
+ # * <tt>:headers</tt>
23
+ # * <tt>:status</tt>
24
+ def initialize(attributes={})
25
+ super attributes
26
+ @status = attributes[:status]
27
+ end
28
+
29
+ # Returns an array of the cookies belonging to the response.
30
+ def cookies
31
+ HTTY::CookiesUtil.cookies_from_string @headers[COOKIES_HEADER_NAME]
32
+ end
33
+
34
+ end
@@ -0,0 +1,29 @@
1
+ # Defines HTTY::Session.
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/request")
4
+
5
+ module HTTY; end
6
+
7
+ # Encapsulates an _htty_ session.
8
+ class HTTY::Session
9
+
10
+ # Returns the requests made during the session.
11
+ attr_reader :requests
12
+
13
+ # Initializes a new HTTY::Session with specified _address_ for the first of
14
+ # the session's #requests.
15
+ def initialize(address)
16
+ @requests = [HTTY::Request.new(address)]
17
+ end
18
+
19
+ # Walks #requests and returns its last HTTY::Response.
20
+ def last_response
21
+ last_request_with_response = requests.reverse.detect do |r|
22
+ r.response
23
+ end
24
+ return nil unless last_request_with_response
25
+
26
+ last_request_with_response.response
27
+ end
28
+
29
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path("#{File.dirname __FILE__}/../app/htty")
4
+
5
+ HTTY::CLI.new(ARGV).run!
@@ -0,0 +1,27 @@
1
+ require 'spec'
2
+ require File.expand_path("#{File.dirname __FILE__}/../../../app/htty/cli")
3
+ require File.expand_path("#{File.dirname __FILE__}/../../../app/htty/request")
4
+
5
+ describe HTTY::CLI do
6
+ describe 'with empty arguments' do
7
+ before :each do
8
+ @cli = HTTY::CLI.new([])
9
+ end
10
+
11
+ it 'should have a session with the URI http://0.0.0.0:80/' do
12
+ @cli.session.requests.should == [HTTY::Request.new('http://0.0.0.0:80/')]
13
+ end
14
+ end
15
+
16
+ describe 'with an address argument' do
17
+ before :each do
18
+ @cli = HTTY::CLI.new(%w(http://njonsson@github.com/njonsson/htty))
19
+ end
20
+
21
+ it 'should have a session with a URI corresponding to the address' do
22
+ @cli.session.requests.should == [HTTY::Request.new('http://' +
23
+ 'njonsson@github.com' +
24
+ '/njonsson/htty')]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec'
2
+ require File.expand_path("#{File.dirname __FILE__}/../../../app/htty/ordered_hash")
3
+
4
+ describe HTTY::OrderedHash do
5
+ describe 'that is empty' do
6
+ before :each do
7
+ @hash = HTTY::OrderedHash.new
8
+ end
9
+
10
+ it 'should be empty' do
11
+ @hash.should be_empty
12
+ end
13
+
14
+ describe '-- when values are added out of order' do
15
+ before :each do
16
+ @hash['foo'] = 'bar'
17
+ @hash['baz'] = 'qux'
18
+ end
19
+
20
+ it '-- should have the expected values' do
21
+ @hash.should == {'foo' => 'bar', 'baz' => 'qux'}
22
+ end
23
+
24
+ it '-- should return the expected array when sent #to_a' do
25
+ @hash.to_a.should == [%w(foo bar), %w(baz qux)]
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'that has values out of order' do
31
+ before :each do
32
+ @hash = HTTY::OrderedHash.new('foo' => 'bar', 'baz' => 'qux')
33
+ end
34
+
35
+ it 'should have the expected values' do
36
+ @hash.should == {'foo' => 'bar', 'baz' => 'qux'}
37
+ end
38
+
39
+ it 'should index the values as expected' do
40
+ @hash['foo'].should == 'bar'
41
+ @hash['baz'].should == 'qux'
42
+ end
43
+
44
+ describe '-- when sent #clear' do
45
+ before :each do
46
+ @hash.clear
47
+ end
48
+
49
+ it '-- should be empty' do
50
+ @hash.should be_empty
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,1236 @@
1
+ require 'spec'
2
+ require File.expand_path("#{File.dirname __FILE__}/../../../app/htty/request")
3
+ require File.expand_path("#{File.dirname __FILE__}/../../../app/htty/response")
4
+
5
+ shared_examples_for 'an empty request' do
6
+ it 'should have only the default headers' do
7
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
8
+ end
9
+
10
+ it 'should have no body' do
11
+ @request.body.should be_nil
12
+ end
13
+
14
+ it 'should have no response' do
15
+ @request.response.should be_nil
16
+ end
17
+ end
18
+
19
+ describe HTTY::Request do
20
+ describe 'initializing with' do
21
+ describe 'an invalid IPv4 address having' do
22
+ describe 'consecutive dots' do
23
+ it 'should raise URI::InvalidURIError' do
24
+ lambda {
25
+ HTTY::Request.new '1.2.3..4'
26
+ }.should raise_error(URI::InvalidURIError)
27
+ end
28
+ end
29
+
30
+ describe 'no dots' do
31
+ it 'should raise URI::InvalidURIError' do
32
+ lambda {
33
+ HTTY::Request.new '1234'
34
+ }.should raise_error(URI::InvalidURIError)
35
+ end
36
+ end
37
+
38
+ describe 'too few dotted decimals' do
39
+ it 'should raise URI::InvalidURIError' do
40
+ lambda {
41
+ HTTY::Request.new '1.2.3'
42
+ }.should raise_error(URI::InvalidURIError)
43
+ end
44
+ end
45
+
46
+ describe 'too many dotted decimals' do
47
+ it 'should raise URI::InvalidURIError' do
48
+ lambda {
49
+ HTTY::Request.new '1.2.3.4.5'
50
+ }.should raise_error(URI::InvalidURIError)
51
+ end
52
+ end
53
+
54
+ describe 'a dotted decimal out of range' do
55
+ it 'should raise URI::InvalidURIError' do
56
+ lambda {
57
+ HTTY::Request.new '1.2.3.1000'
58
+ }.should raise_error(URI::InvalidURIError)
59
+ end
60
+ end
61
+ end
62
+
63
+ describe 'an invalid hostname having a leading hyphen' do
64
+ it 'should raise URI::InvalidURIError' do
65
+ lambda {
66
+ HTTY::Request.new '-google.com'
67
+ }.should raise_error(URI::InvalidURIError)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe 'with a nil address' do
73
+ before :each do
74
+ @request = HTTY::Request.new(nil)
75
+ end
76
+
77
+ it 'should have the URI http://0.0.0.0:80/' do
78
+ @request.uri.should == URI.parse('http://0.0.0.0:80/')
79
+ end
80
+
81
+ it_should_behave_like 'an empty request'
82
+ end
83
+
84
+ describe 'with an empty address' do
85
+ before :each do
86
+ @request = HTTY::Request.new('')
87
+ end
88
+
89
+ it 'should have the URI http://0.0.0.0:80/' do
90
+ @request.uri.should == URI.parse('http://0.0.0.0:80/')
91
+ end
92
+
93
+ it_should_behave_like 'an empty request'
94
+ end
95
+
96
+ describe 'with an address consisting of' do
97
+ describe 'an IPv4 address' do
98
+ before :each do
99
+ @request = HTTY::Request.new('127.0.0.1')
100
+ end
101
+
102
+ it 'should have an HTTP URI for that host' do
103
+ @request.uri.should == URI.parse('http://127.0.0.1:80/')
104
+ end
105
+
106
+ it_should_behave_like 'an empty request'
107
+ end
108
+
109
+ describe 'a hostname' do
110
+ before :each do
111
+ @request = HTTY::Request.new('localhost')
112
+ end
113
+
114
+ it 'should have HTTP URI for that host' do
115
+ @request.uri.should == URI.parse('http://localhost:80/')
116
+ end
117
+
118
+ it_should_behave_like 'an empty request'
119
+
120
+ describe '-- when sent #query_set' do
121
+ describe 'with a query parameter --' do
122
+ before :each do
123
+ @request.query_set 'foo', 'bar'
124
+ end
125
+
126
+ it 'should have a URI including the query parameter' do
127
+ @request.uri.should == URI.parse('http://localhost:80/?foo=bar')
128
+ end
129
+
130
+ it_should_behave_like 'an empty request'
131
+ end
132
+ end
133
+ end
134
+
135
+ describe 'a hostname and a port' do
136
+ before :each do
137
+ @request = HTTY::Request.new('localhost:8080')
138
+ end
139
+
140
+ it 'should have an HTTP URI for that host on that port' do
141
+ @request.uri.should == URI.parse('http://localhost:8080/')
142
+ end
143
+
144
+ it_should_behave_like 'an empty request'
145
+ end
146
+
147
+ describe 'the HTTP scheme and a hostname' do
148
+ before :each do
149
+ @request = HTTY::Request.new('http://localhost')
150
+ end
151
+
152
+ it 'should have an HTTP URI for that host' do
153
+ @request.uri.should == URI.parse('http://localhost:80/')
154
+ end
155
+
156
+ it_should_behave_like 'an empty request'
157
+ end
158
+
159
+ describe 'a hostname and the root path' do
160
+ before :each do
161
+ @request = HTTY::Request.new('github.com/')
162
+ end
163
+
164
+ it 'should have an HTTP URI for the root of that host' do
165
+ @request.uri.should == URI.parse('http://github.com:80/')
166
+ end
167
+
168
+ it_should_behave_like 'an empty request'
169
+ end
170
+
171
+ describe 'the HTTP scheme, a hostname, port 443, and the root path' do
172
+ before :each do
173
+ @request = HTTY::Request.new('http://github.com:443/')
174
+ end
175
+
176
+ it 'should have an HTTP URI for the root of that host on port 443' do
177
+ @request.uri.should == URI.parse('http://github.com:443/')
178
+ end
179
+
180
+ it_should_behave_like 'an empty request'
181
+ end
182
+
183
+ describe 'a hostname and a path' do
184
+ before :each do
185
+ @request = HTTY::Request.new('github.com/explore')
186
+ end
187
+
188
+ it 'should have an HTTP URI for that path on that host' do
189
+ @request.uri.should == URI.parse('http://github.com:80/explore')
190
+ end
191
+
192
+ it_should_behave_like 'an empty request'
193
+ end
194
+
195
+ describe 'a hostname and a query string' do
196
+ before :each do
197
+ @request = HTTY::Request.new('github.com?search=http')
198
+ end
199
+
200
+ it 'should have an HTTP URI for that query string and the root of ' +
201
+ 'that host' do
202
+ @request.uri.should == URI.parse('http://github.com:80/?search=http')
203
+ end
204
+
205
+ it_should_behave_like 'an empty request'
206
+ end
207
+
208
+ describe 'a hostname, a path, and a query string' do
209
+ before :each do
210
+ @request = HTTY::Request.new('github.com/search?q=http&lang=en')
211
+ end
212
+
213
+ it 'should have an HTTP URI for that query string and that path on ' +
214
+ 'that host' do
215
+ @request.uri.should == URI.parse('http://github.com:80' +
216
+ '/search?q=http&lang=en')
217
+ end
218
+
219
+ it_should_behave_like 'an empty request'
220
+ end
221
+
222
+ describe 'a hostname, a path, and a fragment' do
223
+ before :each do
224
+ @request = HTTY::Request.new('github.com/explore#trending')
225
+ end
226
+
227
+ it 'should have an HTTP URI for that fragment of that path on that ' +
228
+ 'host' do
229
+ @request.uri.should == URI.parse('http://github.com:80' +
230
+ '/explore#trending')
231
+ end
232
+
233
+ it_should_behave_like 'an empty request'
234
+ end
235
+
236
+ describe 'a hostname, a port, a path, a query string, and a fragment' do
237
+ before :each do
238
+ @request = HTTY::Request.new('github.com:123/search/deep' +
239
+ '?q=http&lang=en#content')
240
+ end
241
+
242
+ it 'should have an HTTP URI for that query string and that fragment ' +
243
+ 'of that path on that host on that port' do
244
+ @request.uri.should == URI.parse('http://github.com:123' +
245
+ '/search/deep?q=http&lang=en' +
246
+ '#content')
247
+ end
248
+
249
+ it_should_behave_like 'an empty request'
250
+ end
251
+
252
+ describe 'the HTTP scheme, userinfo, a hostname, a port, a path, a query ' +
253
+ 'string, and a fragment' do
254
+ before :each do
255
+ @request = HTTY::Request.new('http://njonsson@github.com:123' +
256
+ '/search/deep?q=http&lang=en#content')
257
+ end
258
+
259
+ describe 'and without a response' do
260
+ it 'should not have a response' do
261
+ @request.response.should be_nil
262
+ end
263
+
264
+ describe '-- and is untouched --' do
265
+ it 'should have an HTTP URI for that query string and that ' +
266
+ 'fragment of that path on that host on that port with that ' +
267
+ 'userinfo' do
268
+ @request.uri.should == URI.parse('http://njonsson@github.com:123' +
269
+ '/search/deep?q=http&lang=en' +
270
+ '#content')
271
+ end
272
+
273
+ it_should_behave_like 'an empty request'
274
+ end
275
+
276
+ describe '-- when sent #address with an address consisting of' do
277
+ describe 'the HTTP scheme and different userinfo, hostname, port, ' +
278
+ 'path, query string, and fragment --' do
279
+ before :each do
280
+ @request.address 'http://steve@mac.com:456/archives/2010' +
281
+ '?author=jobs&subject=html5#flames'
282
+ end
283
+
284
+ it 'should have an HTTP URI for the new query string and the new ' +
285
+ 'fragment of the new path on the new host on the new port ' +
286
+ 'with the new userinfo' do
287
+ @request.uri.should == URI.parse('http://steve@mac.com:456' +
288
+ '/archives/2010' +
289
+ '?author=jobs&subject=html5' +
290
+ '#flames')
291
+ end
292
+
293
+ it_should_behave_like 'an empty request'
294
+ end
295
+
296
+ describe 'a different hostname --' do
297
+ before :each do
298
+ @request.address 'mac.com'
299
+ end
300
+
301
+ it 'should have an HTTP URI for the new host' do
302
+ @request.uri.should == URI.parse('http://mac.com:80/')
303
+ end
304
+
305
+ it_should_behave_like 'an empty request'
306
+ end
307
+ end
308
+
309
+ describe '-- when sent #scheme_set with' do
310
+ describe 'the same scheme --' do
311
+ before :each do
312
+ @request.scheme_set 'http'
313
+ end
314
+
315
+ it 'should have an unchanged URI' do
316
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
317
+ ':123' +
318
+ '/search/deep?q=http&lang=en' +
319
+ '#content')
320
+ end
321
+
322
+ it_should_behave_like 'an empty request'
323
+ end
324
+ end
325
+
326
+ describe '-- when sent #userinfo_set with' do
327
+ describe 'the same userinfo --' do
328
+ before :each do
329
+ @request.userinfo_set 'njonsson'
330
+ end
331
+
332
+ it 'should have an unchanged URI' do
333
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
334
+ ':123' +
335
+ '/search/deep?q=http&lang=en' +
336
+ '#content')
337
+ end
338
+
339
+ it_should_behave_like 'an empty request'
340
+ end
341
+
342
+ describe 'different userinfo --' do
343
+ before :each do
344
+ @request.userinfo_set 'nils'
345
+ end
346
+
347
+ it 'should have the same URI, with the changed userinfo' do
348
+ @request.uri.should == URI.parse('http://nils@github.com:123' +
349
+ '/search/deep?q=http&lang=en' +
350
+ '#content')
351
+ end
352
+
353
+ it_should_behave_like 'an empty request'
354
+ end
355
+ end
356
+
357
+ describe '-- when sent #userinfo_unset --' do
358
+ before :each do
359
+ @request.userinfo_unset
360
+ end
361
+
362
+ it 'should have the same URI, without userinfo' do
363
+ @request.uri.should == URI.parse('http://github.com:123' +
364
+ '/search/deep?q=http&lang=en' +
365
+ '#content')
366
+ end
367
+
368
+ it_should_behave_like 'an empty request'
369
+ end
370
+
371
+ describe '-- when sent #host_set with' do
372
+ describe 'the same host --' do
373
+ before :each do
374
+ @request.host_set 'github.com'
375
+ end
376
+
377
+ it 'should have an unchanged URI' do
378
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
379
+ ':123' +
380
+ '/search/deep?q=http&lang=en' +
381
+ '#content')
382
+ end
383
+
384
+ it_should_behave_like 'an empty request'
385
+ end
386
+
387
+ describe 'a different host --' do
388
+ before :each do
389
+ @request.host_set 'gist.github.com'
390
+ end
391
+
392
+ it 'should have the same URI, with the changed scheme' do
393
+ @request.uri.should == URI.parse('http://' +
394
+ 'njonsson@gist.github.com:123' +
395
+ '/search/deep?q=http&lang=en' +
396
+ '#content')
397
+ end
398
+
399
+ it_should_behave_like 'an empty request'
400
+ end
401
+ end
402
+
403
+ describe '-- when sent #port_set with' do
404
+ describe 'the same port --' do
405
+ before :each do
406
+ @request.port_set 123
407
+ end
408
+
409
+ it 'should have an unchanged URI' do
410
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
411
+ ':123' +
412
+ '/search/deep?q=http&lang=en' +
413
+ '#content')
414
+ end
415
+
416
+ it_should_behave_like 'an empty request'
417
+ end
418
+
419
+ describe 'a different port --' do
420
+ before :each do
421
+ @request.port_set 8888
422
+ end
423
+
424
+ it 'should have the same URI, with the changed scheme' do
425
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
426
+ ':8888' +
427
+ '/search/deep?q=http&lang=en' +
428
+ '#content')
429
+ end
430
+
431
+ it_should_behave_like 'an empty request'
432
+ end
433
+ end
434
+
435
+ describe '-- when sent #path_set with a path consisting of' do
436
+ describe 'a child reference --' do
437
+ before :each do
438
+ @request.path_set 'foo'
439
+ end
440
+
441
+ it 'should have the same URI, descending to the expected path' do
442
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
443
+ ':123' +
444
+ '/search/deep/foo' +
445
+ '?q=http&lang=en#content')
446
+ end
447
+
448
+ it_should_behave_like 'an empty request'
449
+ end
450
+
451
+ describe 'a parent reference --' do
452
+ before :each do
453
+ @request.path_set '..'
454
+ end
455
+
456
+ it 'should have the same URI, ascending to the expected path' do
457
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
458
+ ':123' +
459
+ '/search?q=http&lang=en#content')
460
+ end
461
+
462
+ it_should_behave_like 'an empty request'
463
+ end
464
+
465
+ describe 'an absolute reference --' do
466
+ before :each do
467
+ @request.path_set '/foo/bar'
468
+ end
469
+
470
+ it 'should have the same URI, changing to the expected path' do
471
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
472
+ ':123' +
473
+ '/foo/bar?q=http&lang=en' +
474
+ '#content')
475
+ end
476
+
477
+ it_should_behave_like 'an empty request'
478
+ end
479
+ end
480
+
481
+ describe '-- when sent #query_set' do
482
+ describe 'with a new query parameter --' do
483
+ before :each do
484
+ @request.query_set 'foo', 'bar'
485
+ end
486
+
487
+ it 'should have a URI including the new query parameter' do
488
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
489
+ ':123' +
490
+ '/search/deep' +
491
+ '?q=http&lang=en&foo=bar' +
492
+ '#content')
493
+ end
494
+
495
+ it_should_behave_like 'an empty request'
496
+ end
497
+
498
+ describe 'with a new value for the first query parameter --' do
499
+ before :each do
500
+ @request.query_set 'q', 'ruby'
501
+ end
502
+
503
+ it 'should have a URI with the new value of the query parameter' do
504
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
505
+ ':123' +
506
+ '/search/deep?q=ruby&lang=en' +
507
+ '#content')
508
+ end
509
+
510
+ it_should_behave_like 'an empty request'
511
+ end
512
+
513
+ describe 'with a new value for the second query parameter --' do
514
+ before :each do
515
+ @request.query_set 'lang', 'fr'
516
+ end
517
+
518
+ it 'should have a URI with the new value of the second query ' +
519
+ 'parameter' do
520
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
521
+ ':123' +
522
+ '/search/deep?q=http&lang=fr' +
523
+ '#content')
524
+ end
525
+
526
+ it_should_behave_like 'an empty request'
527
+ end
528
+ end
529
+
530
+ describe '-- when sent #query_unset' do
531
+ describe 'with a nonexistent query parameter --' do
532
+ before :each do
533
+ @request.query_unset 'fizzle'
534
+ end
535
+
536
+ it 'should have an unchanged URI' do
537
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
538
+ ':123' +
539
+ '/search/deep?q=http&lang=en' +
540
+ '#content')
541
+ end
542
+
543
+ it_should_behave_like 'an empty request'
544
+ end
545
+
546
+ describe 'with the first query parameter --' do
547
+ before :each do
548
+ @request.query_unset 'q'
549
+ end
550
+
551
+ it 'should have a URI missing the first query parameter' do
552
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
553
+ ':123' +
554
+ '/search/deep?lang=en#content')
555
+ end
556
+
557
+ it_should_behave_like 'an empty request'
558
+ end
559
+
560
+ describe 'with the second query parameter --' do
561
+ before :each do
562
+ @request.query_unset 'lang'
563
+ end
564
+
565
+ it 'should have a URI missing the second query parameter' do
566
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
567
+ ':123' +
568
+ '/search/deep?q=http#content')
569
+ end
570
+
571
+ it_should_behave_like 'an empty request'
572
+ end
573
+ end
574
+
575
+ describe '-- when sent #query_unset_all --' do
576
+ before :each do
577
+ @request.query_unset_all
578
+ end
579
+
580
+ it 'should have a URI having no query string' do
581
+ @request.uri.should == URI.parse('http://njonsson@github.com:123' +
582
+ '/search/deep#content')
583
+ end
584
+
585
+ it_should_behave_like 'an empty request'
586
+ end
587
+
588
+ describe '-- when sent #fragment_set with' do
589
+ describe 'the same fragment --' do
590
+ before :each do
591
+ @request.fragment_set 'content'
592
+ end
593
+
594
+ it 'should have an unchanged URI' do
595
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
596
+ ':123' +
597
+ '/search/deep?q=http&lang=en' +
598
+ '#content')
599
+ end
600
+
601
+ it_should_behave_like 'an empty request'
602
+ end
603
+
604
+ describe 'different fragment --' do
605
+ before :each do
606
+ @request.fragment_set 'details'
607
+ end
608
+
609
+ it 'should have the same URI, with the changed fragment' do
610
+ @request.uri.should == URI.parse('http://njonsson@github.com' +
611
+ ':123' +
612
+ '/search/deep?q=http&lang=en' +
613
+ '#details')
614
+ end
615
+
616
+ it_should_behave_like 'an empty request'
617
+ end
618
+ end
619
+
620
+ describe '-- when sent #fragment_unset --' do
621
+ before :each do
622
+ @request.fragment_unset
623
+ end
624
+
625
+ it 'should have the same URI, without fragment' do
626
+ @request.uri.should == URI.parse('http://njonsson@github.com:123' +
627
+ '/search/deep?q=http&lang=en')
628
+ end
629
+
630
+ it_should_behave_like 'an empty request'
631
+ end
632
+
633
+ describe '-- when sent #header_set with a new header' do
634
+ before :each do
635
+ @request.header_set 'foo', 'bar'
636
+ end
637
+
638
+ it 'should have an unchanged URI' do
639
+ @request.uri.should == URI.parse('http://njonsson@github.com:123' +
640
+ '/search/deep?q=http&lang=en' +
641
+ '#content')
642
+ end
643
+
644
+ describe '--' do
645
+ it 'should have the header, plus the default headers' do
646
+ @request.headers.should == [%w(User-Agent htty/1.0.0),
647
+ %w(foo bar)]
648
+ end
649
+ end
650
+
651
+ describe 'and then #header_unset' do
652
+ describe 'with the same header name --' do
653
+ before :each do
654
+ @request.header_unset 'foo'
655
+ end
656
+
657
+ it 'should have only the default headers' do
658
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
659
+ end
660
+ end
661
+
662
+ describe 'with a different header name --' do
663
+ before :each do
664
+ @request.header_unset 'qux'
665
+ end
666
+
667
+ it 'should have the header, plus the default headers' do
668
+ @request.headers.should == [%w(User-Agent htty/1.0.0),
669
+ %w(foo bar)]
670
+ end
671
+ end
672
+ end
673
+
674
+ describe 'and then #headers_unset_all --' do
675
+ before :each do
676
+ @request.headers_unset_all
677
+ end
678
+
679
+ it 'should have no headers' do
680
+ @request.headers.should be_empty
681
+ end
682
+ end
683
+ end
684
+
685
+ describe '-- when sent #cookie_add with a cookie' do
686
+ before :each do
687
+ @request.cookie_add 'foo', 'bar'
688
+ end
689
+
690
+ it 'should have an unchanged URI' do
691
+ @request.uri.should == URI.parse('http://njonsson@github.com:123' +
692
+ '/search/deep?q=http&lang=en' +
693
+ '#content')
694
+ end
695
+
696
+ describe '--' do
697
+ it 'should have the cookie' do
698
+ @request.cookies.should == [%w(foo bar)]
699
+ end
700
+
701
+ it 'should have the cookie header, plus the default headers' do
702
+ @request.headers.should == [%w(User-Agent htty/1.0.0),
703
+ %w(Cookie foo=bar)]
704
+ end
705
+ end
706
+
707
+ describe 'and then #cookie_add' do
708
+ describe 'with the same cookie name --' do
709
+ before :each do
710
+ @request.cookie_add 'foo', 'qux'
711
+ end
712
+
713
+ it 'should have the new cookie, plus the old cookie' do
714
+ @request.cookies.should == [%w(foo bar), %w(foo qux)]
715
+ end
716
+
717
+ it 'should have the new cookie header, plus the default ' +
718
+ 'headers' do
719
+ @request.headers.should == [['User-Agent', 'htty/1.0.0'],
720
+ ['Cookie', 'foo=bar; foo=qux']]
721
+ end
722
+ end
723
+
724
+ describe 'with a different cookie name --' do
725
+ before :each do
726
+ @request.cookie_add 'baz', 'qux'
727
+ end
728
+
729
+ it 'should have the new cookie' do
730
+ @request.cookies.should == [%w(foo bar), %w(baz qux)]
731
+ end
732
+
733
+ it 'should have the new cookie header, plus the default ' +
734
+ 'headers' do
735
+ @request.headers.should == [['User-Agent', 'htty/1.0.0'],
736
+ ['Cookie', 'foo=bar; baz=qux']]
737
+ end
738
+ end
739
+
740
+ describe 'with a different cookie name and no value --' do
741
+ before :each do
742
+ @request.cookie_add 'baz'
743
+ end
744
+
745
+ it 'should have the new cookie' do
746
+ @request.cookies.should == [['foo', 'bar'], ['baz', nil]]
747
+ end
748
+
749
+ it 'should have the new cookie header, plus the default ' +
750
+ 'headers' do
751
+ @request.headers.should == [['User-Agent', 'htty/1.0.0'],
752
+ ['Cookie', 'foo=bar; baz']]
753
+ end
754
+ end
755
+ end
756
+
757
+ describe 'and then #cookie_remove' do
758
+ describe 'with the same cookie name --' do
759
+ before :each do
760
+ @request.cookie_remove 'foo'
761
+ end
762
+
763
+ it 'should have no cookie' do
764
+ @request.cookies.should be_empty
765
+ end
766
+
767
+ it 'should have only the default headers' do
768
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
769
+ end
770
+ end
771
+
772
+ describe 'with a different cookie name --' do
773
+ before :each do
774
+ @request.cookie_remove 'qux'
775
+ end
776
+
777
+ it 'should have the cookie' do
778
+ @request.cookies.should == [%w(foo bar)]
779
+ end
780
+
781
+ it 'should have the cookie header, plus the default headers' do
782
+ @request.headers.should == [%w(User-Agent htty/1.0.0),
783
+ %w(Cookie foo=bar)]
784
+ end
785
+ end
786
+ end
787
+
788
+ describe 'and then #cookies_remove_all --' do
789
+ before :each do
790
+ @request.cookies_remove_all
791
+ end
792
+
793
+ it 'should have no cookies' do
794
+ @request.cookies.should be_empty
795
+ end
796
+
797
+ it 'should have only the default headers' do
798
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
799
+ end
800
+ end
801
+
802
+ describe 'and then #address' do
803
+ describe 'with the same host --' do
804
+ before :each do
805
+ @request.address 'http://github.com'
806
+ end
807
+
808
+ it 'should have the cookie' do
809
+ @request.cookies.should == [%w(foo bar)]
810
+ end
811
+
812
+ it 'should have the cookie header, plus the default headers' do
813
+ @request.headers.should == [%w(User-Agent htty/1.0.0),
814
+ %w(Cookie foo=bar)]
815
+ end
816
+ end
817
+
818
+ describe 'with a different host --' do
819
+ before :each do
820
+ @request.address 'http://google.com'
821
+ end
822
+
823
+ it 'should have no cookies' do
824
+ @request.cookies.should == []
825
+ @request.cookies.should be_empty
826
+ end
827
+
828
+ it 'should have only the default headers' do
829
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
830
+ end
831
+ end
832
+ end
833
+ end
834
+
835
+ describe "-- when sent #cookie_add with a new cookie containing '='" do
836
+ before :each do
837
+ @request.cookie_add 'foo', 'bar=baz=qux'
838
+ end
839
+
840
+ describe '--' do
841
+ it 'should have the cookie' do
842
+ @request.cookies.should == [%w(foo bar=baz=qux)]
843
+ end
844
+
845
+ it 'should have the cookie header, plus the default headers' do
846
+ @request.headers.should == [%w(User-Agent htty/1.0.0),
847
+ %w(Cookie foo=bar=baz=qux)]
848
+ end
849
+ end
850
+ end
851
+
852
+ describe '-- when sent #body_set with a body' do
853
+ before :each do
854
+ @request.body_set 'foo'
855
+ end
856
+
857
+ it 'should have an unchanged URI' do
858
+ @request.uri.should == URI.parse('http://njonsson@github.com:123' +
859
+ '/search/deep?q=http&lang=en' +
860
+ '#content')
861
+ end
862
+
863
+ describe '--' do
864
+ it 'should have the body' do
865
+ @request.body.should == 'foo'
866
+ end
867
+
868
+ it 'should have only the default headers' do
869
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
870
+ end
871
+
872
+ it "should have the expected 'Content-Length' header, plus the " +
873
+ "'User-Agent' header if we do not exclude the " +
874
+ "'Content-Length' header" do
875
+ @request.headers(true).should == [%w(User-Agent htty/1.0.0),
876
+ %w(Content-Length 3)]
877
+ end
878
+ end
879
+
880
+ describe 'and then #body_unset' do
881
+ before :each do
882
+ @request.body_unset
883
+ end
884
+
885
+ it 'should have no body' do
886
+ @request.body.should be_nil
887
+ end
888
+
889
+ it 'should have only the default headers' do
890
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
891
+ end
892
+ end
893
+ end
894
+ end
895
+
896
+ describe 'and with a response' do
897
+ before :each do
898
+ @response = HTTY::Response.new
899
+ @request.send :response=, @response
900
+ end
901
+
902
+ it 'should not affect the URI' do
903
+ @request.uri.should == URI.parse('http://njonsson@github.com:123' +
904
+ '/search/deep?q=http&lang=en' +
905
+ '#content')
906
+ end
907
+
908
+ it 'should not affect the headers' do
909
+ @request.headers.should == [%w(User-Agent htty/1.0.0)]
910
+ end
911
+
912
+ it 'should not affect the body' do
913
+ @request.body.should be_nil
914
+ end
915
+
916
+ it 'should not affect the response' do
917
+ @request.response.should == @response
918
+ end
919
+
920
+ describe '-- when sent #address with a different hostname --' do
921
+ before :each do
922
+ @new_request = @request.address('mac.com')
923
+ end
924
+
925
+ it 'should return a request with an HTTP URI for the new host' do
926
+ @new_request.uri.should == URI.parse('http://mac.com:80/')
927
+ end
928
+
929
+ it 'should return a request without a response' do
930
+ @new_request.response.should be_nil
931
+ end
932
+ end
933
+
934
+ describe '-- when sent #scheme_set with a different scheme --' do
935
+ before :each do
936
+ @new_request = @request.scheme_set('http')
937
+ end
938
+
939
+ it 'should return a request with the same URI having the changed ' +
940
+ 'scheme' do
941
+ @new_request.uri.should == URI.parse('http://njonsson@github.com' +
942
+ ':123' +
943
+ '/search/deep?q=http&lang=en' +
944
+ '#content')
945
+ end
946
+
947
+ it 'should return a request without a response' do
948
+ @new_request.response.should be_nil
949
+ end
950
+ end
951
+
952
+ describe '-- when sent #userinfo_set with different userinfo --' do
953
+ before :each do
954
+ @new_request = @request.userinfo_set('nils')
955
+ end
956
+
957
+ it 'should return a request with the same URI having the changed ' +
958
+ 'userinfo' do
959
+ @new_request.uri.should == URI.parse('http://nils@github.com' +
960
+ ':123' +
961
+ '/search/deep' +
962
+ '?q=http&lang=en' +
963
+ '#content')
964
+ end
965
+
966
+ it 'should return a request without a response' do
967
+ @new_request.response.should be_nil
968
+ end
969
+ end
970
+
971
+ describe '-- when sent #userinfo_unset --' do
972
+ before :each do
973
+ @new_request = @request.userinfo_unset
974
+ end
975
+
976
+ it 'should return a request with the same URI not having userinfo' do
977
+ @new_request.uri.should == URI.parse('http://github.com:123' +
978
+ '/search/deep?q=http&lang=en' +
979
+ '#content')
980
+ end
981
+
982
+ it 'should return a request without a response' do
983
+ @new_request.response.should be_nil
984
+ end
985
+ end
986
+
987
+ describe '-- when sent #host_set with a different host --' do
988
+ before :each do
989
+ @new_request = @request.host_set('gist.github.com')
990
+ end
991
+
992
+ it 'should return a request with the same URI having the changed ' +
993
+ 'host' do
994
+ @new_request.uri.should == URI.parse('http://' +
995
+ 'njonsson@gist.github.com' +
996
+ ':123' +
997
+ '/search/deep?q=http&lang=en' +
998
+ '#content')
999
+ end
1000
+
1001
+ it 'should return a request without a response' do
1002
+ @new_request.response.should be_nil
1003
+ end
1004
+ end
1005
+
1006
+ describe '-- when sent #port_set with a different port --' do
1007
+ before :each do
1008
+ @new_request = @request.port_set(8888)
1009
+ end
1010
+
1011
+ it 'should return a request with the same URI having the changed ' +
1012
+ 'port' do
1013
+ @new_request.uri.should == URI.parse('http://njonsson@github.com' +
1014
+ ':8888' +
1015
+ '/search/deep?q=http&lang=en' +
1016
+ '#content')
1017
+ end
1018
+
1019
+ it 'should return a request without a response' do
1020
+ @new_request.response.should be_nil
1021
+ end
1022
+ end
1023
+
1024
+ describe '-- when sent #path_set with a different path --' do
1025
+ before :each do
1026
+ @new_request = @request.path_set('foo')
1027
+ end
1028
+
1029
+ it 'should return a request with the same URI having the changed ' +
1030
+ 'path' do
1031
+ @new_request.uri.should == URI.parse('http://njonsson@github.com' +
1032
+ ':123' +
1033
+ '/search/deep/foo' +
1034
+ '?q=http&lang=en#content')
1035
+ end
1036
+
1037
+ it 'should return a request without a response' do
1038
+ @new_request.response.should be_nil
1039
+ end
1040
+ end
1041
+
1042
+ describe '-- when sent #query_set with a query parameter --' do
1043
+ before :each do
1044
+ @new_request = @request.query_set('foo', 'bar')
1045
+ end
1046
+
1047
+ it 'should return a request with the same URI having the new query ' +
1048
+ 'parameter' do
1049
+ @new_request.uri.should == URI.parse('http://njonsson@github.com' +
1050
+ ':123' +
1051
+ '/search/deep' +
1052
+ '?q=http&lang=en&foo=bar' +
1053
+ '#content')
1054
+ end
1055
+
1056
+ it 'should return a request without a response' do
1057
+ @new_request.response.should be_nil
1058
+ end
1059
+ end
1060
+
1061
+ describe '-- when sent #query_unset with the first query ' +
1062
+ 'parameter --' do
1063
+ before :each do
1064
+ @new_request = @request.query_unset('q')
1065
+ end
1066
+
1067
+ it 'should return a request with the same URI missing the first ' +
1068
+ 'query parameter' do
1069
+ @new_request.uri.should == URI.parse('http://njonsson@github.com' +
1070
+ ':123' +
1071
+ '/search/deep?lang=en#content')
1072
+ end
1073
+
1074
+ it 'should return a request without a response' do
1075
+ @new_request.response.should be_nil
1076
+ end
1077
+ end
1078
+
1079
+ describe '-- when sent #query_unset_all --' do
1080
+ before :each do
1081
+ @new_request = @request.query_unset_all
1082
+ end
1083
+
1084
+ it 'should return a request with the same URI having no query ' +
1085
+ 'string' do
1086
+ @new_request.uri.should == URI.parse('http://' +
1087
+ 'njonsson@github.com:123' +
1088
+ '/search/deep#content')
1089
+ end
1090
+
1091
+ it 'should return a request without a response' do
1092
+ @new_request.response.should be_nil
1093
+ end
1094
+ end
1095
+
1096
+ describe '-- when sent #fragment_set with a different fragment --' do
1097
+ before :each do
1098
+ @new_request = @request.fragment_set('details')
1099
+ end
1100
+
1101
+ it 'should return a request with the same URI having the changed ' +
1102
+ 'fragment' do
1103
+ @new_request.uri.should == URI.parse('http://njonsson@github.com' +
1104
+ ':123' +
1105
+ '/search/deep?q=http&lang=en' +
1106
+ '#details')
1107
+ end
1108
+
1109
+ it 'should return a request without a response' do
1110
+ @new_request.response.should be_nil
1111
+ end
1112
+ end
1113
+
1114
+ describe '-- when sent #fragment_unset --' do
1115
+ before :each do
1116
+ @new_request = @request.fragment_unset
1117
+ end
1118
+
1119
+ it 'should return a request with the same URI missing the fragment' do
1120
+ @new_request.uri.should == URI.parse('http://' +
1121
+ 'njonsson@github.com:123' +
1122
+ '/search/deep?q=http&lang=en')
1123
+ end
1124
+
1125
+ it 'should return a request without a response' do
1126
+ @new_request.response.should be_nil
1127
+ end
1128
+ end
1129
+
1130
+ describe '-- when sent #header_set with a new header' do
1131
+ before :each do
1132
+ @new_request = @request.header_set('foo', 'bar')
1133
+ end
1134
+
1135
+ it 'should return a request with an unchanged URI' do
1136
+ @new_request.uri.should == URI.parse('http://' +
1137
+ 'njonsson@github.com:123' +
1138
+ '/search/deep?q=http&lang=en' +
1139
+ '#content')
1140
+ end
1141
+
1142
+ it 'should return a request with no response' do
1143
+ @new_request.response.should be_nil
1144
+ end
1145
+
1146
+ describe '--' do
1147
+ it 'should return a request with the header, plus the default ' +
1148
+ 'headers' do
1149
+ @new_request.headers.should == [%w(User-Agent htty/1.0.0),
1150
+ %w(foo bar)]
1151
+ end
1152
+
1153
+ it 'should return a request without a response' do
1154
+ @new_request.response.should be_nil
1155
+ end
1156
+ end
1157
+
1158
+ describe 'and then #header_unset' do
1159
+ describe 'with the same header name --' do
1160
+ before :each do
1161
+ @new_request = @request.header_unset('foo')
1162
+ end
1163
+
1164
+ it 'should return a request with only the default headers' do
1165
+ @new_request.headers.should == [%w(User-Agent htty/1.0.0)]
1166
+ end
1167
+ end
1168
+ end
1169
+
1170
+ describe 'and then #headers_unset_all --' do
1171
+ before :each do
1172
+ @new_request = @request.headers_unset_all
1173
+ end
1174
+
1175
+ it 'should return a request with no headers' do
1176
+ @new_request.headers.should be_empty
1177
+ end
1178
+ end
1179
+ end
1180
+
1181
+ describe '-- when sent #body_set with a body' do
1182
+ before :each do
1183
+ @new_request = @request.body_set('foo')
1184
+ end
1185
+
1186
+ it 'should return a request with an unchanged URI' do
1187
+ @new_request.uri.should == URI.parse('http://' +
1188
+ 'njonsson@github.com:123' +
1189
+ '/search/deep?q=http&lang=en' +
1190
+ '#content')
1191
+ end
1192
+
1193
+ it 'should return a request with no response' do
1194
+ @new_request.response.should be_nil
1195
+ end
1196
+
1197
+ describe '--' do
1198
+ it 'should return a request with the body' do
1199
+ @new_request.body.should == 'foo'
1200
+ end
1201
+
1202
+ it 'should return a request with only the default headers' do
1203
+ @new_request.headers.should == [%w(User-Agent htty/1.0.0)]
1204
+ end
1205
+
1206
+ it "should return a request with the expected 'Content-Length' " +
1207
+ "header, plus the 'User-Agent' header if we do not exclude " +
1208
+ "the 'Content-Length' header" do
1209
+ @new_request.headers(true).should == [['User-Agent', 'htty/' +
1210
+ '1.0.0'],
1211
+ ['Content-Length', '3']]
1212
+ end
1213
+
1214
+ it 'should return a request without a response' do
1215
+ @new_request.response.should be_nil
1216
+ end
1217
+ end
1218
+
1219
+ describe 'and then #body_unset' do
1220
+ before :each do
1221
+ @new_request = @request.body_unset
1222
+ end
1223
+
1224
+ it 'should return a request with no body' do
1225
+ @new_request.body.should be_nil
1226
+ end
1227
+
1228
+ it 'should return a request with only the default headers' do
1229
+ @new_request.headers.should == [%w(User-Agent htty/1.0.0)]
1230
+ end
1231
+ end
1232
+ end
1233
+ end
1234
+ end
1235
+ end
1236
+ end