1require 'rubygems/test_case'
2require 'rubygems/server'
3require 'stringio'
4
5class Gem::Server
6  attr_reader :server
7end
8
9class TestGemServer < Gem::TestCase
10  def setup
11    super
12
13    @a1 = quick_gem 'a', '1'
14    @a2 = quick_gem 'a', '2'
15
16    @server = Gem::Server.new Gem.dir, process_based_port, false
17    @req = WEBrick::HTTPRequest.new :Logger => nil
18    @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
19  end
20
21  def test_doc_root_3
22    orig_rdoc_version = Gem::RDoc.rdoc_version
23    Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12')
24
25    assert_equal '/doc_root/X-1/rdoc/index.html', @server.doc_root('X-1')
26
27  ensure
28    Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version
29  end
30
31  def test_doc_root_4
32    orig_rdoc_version = Gem::RDoc.rdoc_version
33    Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('4.0')
34
35    assert_equal '/doc_root/X-1/', @server.doc_root('X-1')
36
37  ensure
38    Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version
39  end
40
41  def test_have_rdoc_4_plus_eh
42    orig_rdoc_version = Gem::RDoc.rdoc_version
43    Gem::RDoc.instance_variable_set(:@rdoc_version, Gem::Version.new('4.0'))
44
45    server = Gem::Server.new Gem.dir, 0, false
46    assert server.have_rdoc_4_plus?
47
48    Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12')
49
50    server = Gem::Server.new Gem.dir, 0, false
51    refute server.have_rdoc_4_plus?
52
53    Gem::RDoc.instance_variable_set(:@rdoc_version,
54                                    Gem::Version.new('4.0.0.preview2'))
55
56    server = Gem::Server.new Gem.dir, 0, false
57    assert server.have_rdoc_4_plus?
58  ensure
59    Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version
60  end
61
62  def test_spec_dirs
63    s = Gem::Server.new Gem.dir, process_based_port, false
64
65    assert_equal [File.join(Gem.dir, 'specifications')], s.spec_dirs
66
67    s = Gem::Server.new [Gem.dir, Gem.dir], process_based_port, false
68
69    assert_equal [File.join(Gem.dir, 'specifications'),
70                  File.join(Gem.dir, 'specifications')], s.spec_dirs
71  end
72
73  def test_latest_specs
74    data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
75    @req.parse data
76
77    Gem::Deprecate.skip_during do
78      @server.latest_specs @req, @res
79    end
80
81    assert_equal 200, @res.status, @res.body
82    assert_match %r| \d\d:\d\d:\d\d |, @res['date']
83    assert_equal 'application/octet-stream', @res['content-type']
84    assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
85    Marshal.load(@res.body)
86  end
87
88  def test_latest_specs_gemdirs
89    data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
90    dir = "#{@gemhome}2"
91
92    spec = quick_spec 'z', 9
93
94    specs_dir = File.join dir, 'specifications'
95    FileUtils.mkdir_p specs_dir
96
97    open File.join(specs_dir, spec.spec_name), 'w' do |io|
98      io.write spec.to_ruby
99    end
100
101    server = Gem::Server.new dir, process_based_port, false
102
103    @req.parse data
104
105    server.latest_specs @req, @res
106
107    assert_equal 200, @res.status
108
109    assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body)
110  end
111
112  def test_latest_specs_gz
113    data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
114    @req.parse data
115
116    Gem::Deprecate.skip_during do
117      @server.latest_specs @req, @res
118    end
119
120    assert_equal 200, @res.status, @res.body
121    assert_match %r| \d\d:\d\d:\d\d |, @res['date']
122    assert_equal 'application/x-gzip', @res['content-type']
123    assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
124                 Marshal.load(Gem.gunzip(@res.body))
125  end
126
127  def test_listen
128    util_listen
129
130    capture_io do
131      @server.listen
132    end
133
134    assert_equal 1, @server.server.listeners.length
135  end
136
137  def test_listen_addresses
138    util_listen
139
140    capture_io do
141      @server.listen %w[a b]
142    end
143
144    assert_equal 2, @server.server.listeners.length
145  end
146
147  def test_quick_gemdirs
148    data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n"
149    dir = "#{@gemhome}2"
150
151    server = Gem::Server.new dir, process_based_port, false
152
153    @req.parse data
154
155    server.quick @req, @res
156
157    assert_equal 404, @res.status
158
159    spec = quick_spec 'z', 9
160
161    specs_dir = File.join dir, 'specifications'
162
163    FileUtils.mkdir_p specs_dir
164
165    open File.join(specs_dir, spec.spec_name), 'w' do |io|
166      io.write spec.to_ruby
167    end
168
169    data.rewind
170
171    req = WEBrick::HTTPRequest.new :Logger => nil
172    res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
173    req.parse data
174
175    server.quick req, res
176
177    assert_equal 200, res.status
178  end
179
180  def test_quick_missing
181    data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n"
182    @req.parse data
183
184    @server.quick @req, @res
185
186    assert_equal 404, @res.status, @res.body
187    assert_match %r| \d\d:\d\d:\d\d |, @res['date']
188    assert_equal 'text/plain', @res['content-type']
189    assert_equal 'No gems found matching "z" "9" nil', @res.body
190    assert_equal 404, @res.status
191  end
192
193  def test_quick_marshal_a_1_gemspec_rz
194    data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1.gemspec.rz HTTP/1.0\r\n\r\n"
195    @req.parse data
196
197    @server.quick @req, @res
198
199    assert_equal 200, @res.status, @res.body
200    assert @res['date']
201    assert_equal 'application/x-deflate', @res['content-type']
202
203    spec = Marshal.load Gem.inflate(@res.body)
204    assert_equal 'a', spec.name
205    assert_equal Gem::Version.new(1), spec.version
206  end
207
208  def test_quick_marshal_a_1_mswin32_gemspec_rz
209    quick_gem 'a', '1' do |s| s.platform = Gem::Platform.local end
210
211    data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1-#{Gem::Platform.local}.gemspec.rz HTTP/1.0\r\n\r\n"
212    @req.parse data
213
214    @server.quick @req, @res
215
216    assert_equal 200, @res.status, @res.body
217    assert @res['date']
218    assert_equal 'application/x-deflate', @res['content-type']
219
220    spec = Marshal.load Gem.inflate(@res.body)
221    assert_equal 'a', spec.name
222    assert_equal Gem::Version.new(1), spec.version
223    assert_equal Gem::Platform.local, spec.platform
224  end
225
226  def test_rdoc
227    data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n"
228    @req.parse data
229
230    @server.rdoc @req, @res
231
232    assert_equal 200, @res.status, @res.body
233    assert_match %r|No documentation found|, @res.body
234    assert_equal 'text/html', @res['content-type']
235  end
236
237  def test_root
238    data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
239    @req.parse data
240
241    @server.root @req, @res
242
243    assert_equal 200, @res.status, @res.body
244    assert_match %r| \d\d:\d\d:\d\d |, @res['date']
245    assert_equal 'text/html', @res['content-type']
246  end
247
248  def test_root_gemdirs
249    data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
250    dir = "#{@gemhome}2"
251
252    spec = quick_spec 'z', 9
253
254    specs_dir = File.join dir, 'specifications'
255    FileUtils.mkdir_p specs_dir
256
257    open File.join(specs_dir, spec.spec_name), 'w' do |io|
258      io.write spec.to_ruby
259    end
260
261    server = Gem::Server.new dir, process_based_port, false
262
263    @req.parse data
264
265    server.root @req, @res
266
267    assert_equal 200, @res.status
268    assert_match 'z 9', @res.body
269  end
270
271  def test_specs
272    data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
273    @req.parse data
274
275    @server.specs @req, @res
276
277    assert_equal 200, @res.status, @res.body
278    assert_match %r| \d\d:\d\d:\d\d |, @res['date']
279    assert_equal 'application/octet-stream', @res['content-type']
280
281    assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY],
282                  ['a', Gem::Version.new(2), Gem::Platform::RUBY]],
283                 Marshal.load(@res.body)
284  end
285
286  def test_specs_gemdirs
287    data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
288    dir = "#{@gemhome}2"
289
290    spec = quick_spec 'z', 9
291
292    specs_dir = File.join dir, 'specifications'
293    FileUtils.mkdir_p specs_dir
294
295    open File.join(specs_dir, spec.spec_name), 'w' do |io|
296      io.write spec.to_ruby
297    end
298
299    server = Gem::Server.new dir, process_based_port, false
300
301    @req.parse data
302
303    server.specs @req, @res
304
305    assert_equal 200, @res.status
306
307    assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body)
308  end
309
310  def test_specs_gz
311    data = StringIO.new "GET /specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
312    @req.parse data
313
314    @server.specs @req, @res
315
316    assert_equal 200, @res.status, @res.body
317    assert_match %r| \d\d:\d\d:\d\d |, @res['date']
318    assert_equal 'application/x-gzip', @res['content-type']
319
320    assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY],
321                  ['a', Gem::Version.new(2), Gem::Platform::RUBY]],
322                 Marshal.load(Gem.gunzip(@res.body))
323  end
324
325  def util_listen
326    webrick = Object.new
327    webrick.instance_variable_set :@listeners, []
328    def webrick.listeners() @listeners end
329    def webrick.listen(host, port)
330      socket = Object.new
331      socket.instance_variable_set :@host, host
332      socket.instance_variable_set :@port, port
333      def socket.addr() [nil, @port, @host] end
334      @listeners << socket
335    end
336
337    @server.instance_variable_set :@server, webrick
338  end
339end
340