htty 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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