serverside 0.4.1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,287 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ include ServerSide::HTTP
4
+
5
+ context "Response.new" do
6
+ specify "should use a default status of 200 OK" do
7
+ @res = Response.new
8
+ @res.status.should == '200 OK'
9
+ end
10
+
11
+ specify "should extract status from options" do
12
+ @res = Response.new(:status => 'aok')
13
+ @res.status.should == 'aok'
14
+ end
15
+
16
+ specify "should extract body from options" do
17
+ @res = Response.new(:status => 200, :body => 'hello!')
18
+ @res.body.should == 'hello!'
19
+ end
20
+
21
+ specify "should extract headers from options" do
22
+ @res = Response.new(:status => 200, :content_type => 'text/html')
23
+ @res.status.should == 200
24
+ @res.headers.size.should == 1
25
+ @res.headers[0].should == "Content-Type: text/html\r\n"
26
+ end
27
+
28
+ specify "should default body to empty string" do
29
+ @res = Response.new
30
+ @res.body.should == ''
31
+
32
+ @res = Response.new(:body => nil)
33
+ @res.body.should be_nil
34
+ end
35
+ end
36
+
37
+ context "Response.redirect" do
38
+ setup do
39
+ @res = Response.redirect('foobar.html')
40
+ end
41
+
42
+ specify "should default to temporary redirect" do
43
+ @res.status.should == STATUS_FOUND
44
+ end
45
+
46
+ specify "should support custom status" do
47
+ @res = Response.redirect('foobar.html', 'BBQ')
48
+ @res.status.should == 'BBQ'
49
+ end
50
+
51
+ specify "should include a location header with the redirect url" do
52
+ @res.headers.should == ["Location: foobar.html\r\n"]
53
+ end
54
+ end
55
+
56
+ context "Response.static" do
57
+ setup do
58
+ @t = Time.now
59
+ @res = Response.static(__FILE__)
60
+ end
61
+
62
+ specify "should have the file content as the body" do
63
+ @res.body.should == IO.read(__FILE__)
64
+ end
65
+
66
+ specify "should raise not found error for an unknown file" do
67
+ proc {Response.static('xxx_yyy_zzz')}.should raise_error(NotFoundError)
68
+ end
69
+
70
+ specify "should set cache headers correctly" do
71
+ s = @res.to_s
72
+ s.should =~ /\r\nETag: "#{Regexp.quote(File.etag(__FILE__))}"\r\n/
73
+ s.should =~ /\r\nLast-Modified: #{File.mtime(__FILE__).httpdate}\r\n/
74
+ s.should =~ /\r\nExpires: #{(@t + 86400).httpdate}\r\n/
75
+ end
76
+
77
+ specify "should validate the client's cache" do
78
+ 1.should == 1
79
+ end
80
+
81
+ specify "should be able to serve directories" do
82
+ proc {Response.static('.')}.should_not raise_error
83
+ end
84
+ end
85
+
86
+ context "Response.to_s" do
87
+ specify "should render the status correctly" do
88
+ r = Response.new
89
+ s = r.to_s
90
+ s.should =~ /^HTTP\/1.1 200 OK\r\n/
91
+
92
+ r = Response.new(:status => '400 Bad Request')
93
+ s = r.to_s
94
+ s.should =~ /^HTTP\/1.1 400 Bad Request\r\n/
95
+ end
96
+
97
+ specify "should include a Date header" do
98
+ r = Response.new
99
+ s = r.to_s
100
+ s.should =~ /^HTTP\/1.1 200 OK\r\nDate: (.+)\r\n/
101
+
102
+ # extract stamp
103
+ s =~ /^HTTP\/1.1 200 OK\r\nDate: (.+)\r\n/
104
+ proc {Time.parse($1)}.should_not raise_error
105
+ end
106
+
107
+ specify "should include blank line before the body" do
108
+ r = Response.new
109
+ s = r.to_s
110
+ s.should =~ /(.+)\r\n\r\n$/
111
+
112
+ r = Response.new(:body => 'test')
113
+ s = r.to_s
114
+ s.should =~ /(.+)\r\n\r\ntest$/
115
+ end
116
+
117
+ specify "should include a content_length unless body is nil" do
118
+ b = 'a' * (rand(30) + 30)
119
+ r = Response.new(:body => b)
120
+ s = r.to_s
121
+ s.should =~ /Content-Length: #{b.size}\r\n\r\n#{b}$/
122
+
123
+ r = Response.new(:body => nil)
124
+ s = r.to_s
125
+ s.should_not =~ /Content-Length/
126
+ end
127
+
128
+ specify "should not include a content_length if streaming" do
129
+ r = Response.new(:body => 'test')
130
+ r.stream(1) {}
131
+ s = r.to_s
132
+ s.should_not =~ /Content-Length/
133
+ s.should =~ /\r\n\r\ntest$/
134
+ end
135
+
136
+ specify "should include all headers in the response" do
137
+ r = Response.new(:body => nil)
138
+ r.add_header('ABC', 123)
139
+ r.add_header('DEF', 456)
140
+ s = r.to_s
141
+
142
+ s.should =~ /\r\nABC: 123\r\nDEF: 456\r\n\r\n$/
143
+ end
144
+ end
145
+
146
+ context "Response.add_header" do
147
+ setup do
148
+ @res = Response.new
149
+ end
150
+
151
+ specify "should a header to the response's headers" do
152
+ @res.add_header('ABC', '123')
153
+ @res.headers.should == ["ABC: 123\r\n"]
154
+
155
+ @res.add_header('DEF', '456')
156
+ @res.headers.should == ["ABC: 123\r\n", "DEF: 456\r\n"]
157
+ end
158
+
159
+ specify "should be always additive" do
160
+ @res.add_header('ABC', '123')
161
+ @res.add_header('ABC', '456')
162
+ @res.headers.should == ["ABC: 123\r\n", "ABC: 456\r\n"]
163
+ end
164
+ end
165
+
166
+ context "Response.set_cookie" do
167
+ setup do
168
+ @res = Response.new
169
+ end
170
+
171
+ specify "should add a cookie header" do
172
+ t = Time.now + 1000
173
+ @res.set_cookie(:abc, '2 3 4', :expires => t)
174
+ @res.headers.should == ["Set-Cookie: abc=2+3+4; path=/; expires=#{t.httpdate}\r\n"]
175
+ end
176
+
177
+ specify "should accept a path option" do
178
+ t = Time.now + 1000
179
+ @res.set_cookie(:abc, '2 3 4', :path => '/def', :expires => t)
180
+ @res.headers.should == ["Set-Cookie: abc=2+3+4; path=/def; expires=#{t.httpdate}\r\n"]
181
+ end
182
+
183
+ specify "should accept a domain option" do
184
+ t = Time.now + 1000
185
+ @res.set_cookie(:abc, '2 3 4', :domain => 'test.net', :expires => t)
186
+ @res.headers.should == ["Set-Cookie: abc=2+3+4; path=/; expires=#{t.httpdate}; domain=test.net\r\n"]
187
+ end
188
+
189
+ specify "should accept a ttl option" do
190
+ t = Time.now + 1000
191
+ @res.set_cookie(:abc, '2 3 4', :ttl => 1000)
192
+ @res.headers.should == ["Set-Cookie: abc=2+3+4; path=/; expires=#{t.httpdate}\r\n"]
193
+ end
194
+ end
195
+
196
+ context "Response.cache" do
197
+ setup do
198
+ @res = Response.new
199
+ end
200
+
201
+ specify "should support a :cache_control option" do
202
+ @res.cache(:cache_control => 'public')
203
+ @res.headers.should == ["Cache-Control: public\r\n"]
204
+ end
205
+
206
+ specify "should support an :expires option" do
207
+ t = Time.now + 1000
208
+ @res.cache(:expires => t)
209
+ @res.headers.should == ["Expires: #{t.httpdate}\r\n"]
210
+ end
211
+
212
+ specify "should support a :ttl option" do
213
+ t = Time.now + 1000
214
+ @res.cache(:ttl => 1000)
215
+ @res.headers.should == ["Expires: #{t.httpdate}\r\n"]
216
+ end
217
+
218
+ specify "should remove the cache-control header if present" do
219
+ @res.add_header('Cache-Control', 'max-age=300')
220
+ @res.headers.should == ["Cache-Control: max-age=300\r\n"]
221
+ t = Time.now + 1000
222
+ @res.cache(:expires => t)
223
+ @res.headers.should == ["Expires: #{t.httpdate}\r\n"]
224
+ end
225
+ end
226
+
227
+ context "Response.validate_cache" do
228
+ setup do
229
+ @req = Request.new(nil)
230
+ @last_modified = Time.now - 300
231
+ @req.headers['If-None-Match'] = '"abcde"'
232
+ @req.headers['If-Modified-Since'] = @last_modified.httpdate
233
+
234
+ @res = Response.new(:request => @req)
235
+ end
236
+
237
+ specify "should validate against an etag validator" do
238
+ @res.validate_cache(:etag => 'abcde')
239
+ @res.status.should == '304 Not Modified'
240
+ end
241
+
242
+ specify "should validate against a last-modified validator" do
243
+ @res.validate_cache(:last_modified => @last_modified)
244
+ @res.status.should == '304 Not Modified'
245
+ end
246
+
247
+ specify "should yield to the supplied block if the cache is not validated" do
248
+ @res.validate_cache(:etag => 'defgh') do |r|
249
+ r.status = '204'
250
+ r.body = 'hey there hey'
251
+ end
252
+
253
+ @res.status.should == '204'
254
+ @res.body.should == 'hey there hey'
255
+ end
256
+
257
+ specify "should set cache-related headers" do
258
+ t = Time.now + 1000
259
+ @res.validate_cache(:etag => 'defgh', :expires => t) do |r|
260
+ r.status = '204'
261
+ r.body = 'hey there hey'
262
+ end
263
+ s = @res.to_s
264
+ s.should =~ /\r\nETag: "defgh"\r\n/
265
+ s.should =~ /\r\nExpires: #{t.httpdate}\r\n/
266
+
267
+ @res = Response.new(:request => @req)
268
+ t = Time.now + 1000
269
+ @res.validate_cache(:etag => 'defgh', :ttl => 1000) do |r|
270
+ r.status = '204'
271
+ r.body = 'hey there hey'
272
+ end
273
+ s = @res.to_s
274
+ s.should =~ /\r\nETag: "defgh"\r\n/
275
+ s.should =~ /\r\nExpires: #{t.httpdate}\r\n/
276
+
277
+ @res = Response.new(:request => @req)
278
+ t = Time.now
279
+ @res.validate_cache(:last_modified => t, :cache_control => 'private') do |r|
280
+ r.status = '204'
281
+ r.body = 'hey there hey'
282
+ end
283
+ s = @res.to_s
284
+ s.should =~ /\r\nLast-Modified: #{t.httpdate}\r\n/
285
+ s.should =~ /\r\nCache-Control: private\r\n/
286
+ end
287
+ end
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), '../lib/serverside')
2
+
3
+ include ServerSide::HTTP
4
+
5
+ class Request
6
+ attr_writer :persistent
7
+ end
8
+
9
+ class SpecHTTPServer
10
+ include Server
11
+
12
+ attr_accessor :in, :state
13
+
14
+ def initialize
15
+ reset
16
+ end
17
+
18
+ def reset
19
+ post_init
20
+ @response = ''
21
+ @response_headers = []
22
+ @closed = false
23
+ end
24
+
25
+ attr_accessor :response, :closed
26
+
27
+ def send_data(data)
28
+ @response << data
29
+ end
30
+
31
+ def close_connection_after_writing
32
+ @closed = true
33
+ end
34
+
35
+ def handle_error(e)
36
+ raise e
37
+ end
38
+ end
39
+
@@ -1,6 +1,4 @@
1
- __END__
2
-
3
- require File.join(File.dirname(__FILE__), '../lib/serverside')
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
4
2
  require 'stringio'
5
3
  require 'fileutils'
6
4
 
@@ -25,20 +23,20 @@ include ServerSide
25
23
  context "ServerSide::Template.set" do
26
24
  specify "should add an consisting of stamp and template to the templates hash" do
27
25
  Template.reset
28
- Template.templates.should_be_empty
26
+ Template.templates.should be_empty
29
27
  t = Time.now
30
28
  Template.set('test', 'hello', t)
31
- Template.templates.include?('test').should_be true
29
+ Template.templates.include?('test').should be_true
32
30
  a = Template.templates['test']
33
- a.should_be_a_kind_of Array
31
+ a.should be_a_kind_of(Array)
34
32
  a.size.should == 2
35
- a.first.should_be t
36
- a.last.should_be_a_kind_of Erubis::Eruby
33
+ a.first.should be(t)
34
+ a.last.should be_a_kind_of(Erubis::Eruby)
37
35
  end
38
36
 
39
37
  specify "should set stamp to nil by default" do
40
38
  Template.set('test', 'hello')
41
- Template.templates['test'].first.should_be_nil
39
+ Template.templates['test'].first.should be_nil
42
40
  end
43
41
 
44
42
  specify "should construct a new Erubis::Eruby instance with the body" do
@@ -50,25 +48,25 @@ end
50
48
  context "ServerSide::Template.validate" do
51
49
  specify "should return nil for a non-existant template" do
52
50
  Template.reset
53
- Template.validate('test').should_be_nil
54
- Template.validate('invalid_file_ref').should_be_nil
51
+ Template.validate('test').should be_nil
52
+ Template.validate('invalid_file_ref').should be_nil
55
53
  end
56
54
 
57
55
  specify "should load a file as template if the name references a file" do
58
56
  Template.reset
59
57
  t = Template.validate(__FILE__)
60
- t.should_be_a_kind_of Erubis::Eruby
58
+ t.should be_a_kind_of(Erubis::Eruby)
61
59
  t.result(binding).should == IO.read(__FILE__)
62
60
  Template.templates.size.should == 1
63
61
  t = Template.templates[__FILE__]
64
62
  t.first.should == File.mtime(__FILE__)
65
- t.last.should_be_a_kind_of Erubis::Eruby
63
+ t.last.should be_a_kind_of(Erubis::Eruby)
66
64
  end
67
65
 
68
66
  specify "should return the Erubis::Eruby instance for an existing template" do
69
67
  Template.reset
70
68
  t = Template.validate(__FILE__)
71
- t.should_be_a_kind_of Erubis::Eruby
69
+ t.should be_a_kind_of(Erubis::Eruby)
72
70
  t.result(binding).should == IO.read(__FILE__)
73
71
  end
74
72
 
@@ -90,15 +88,15 @@ context "ServerSide::Template.validate" do
90
88
  Template.validate('tmp').result(binding).should == '1'
91
89
  Template.templates['tmp'].first.should == File.mtime('tmp')
92
90
  FileUtils.rm('tmp')
93
- Template.validate('tmp').should_be_nil
94
- Template.templates['tmp'].should_be_nil
91
+ Template.validate('tmp').should be_nil
92
+ Template.templates['tmp'].should be_nil
95
93
  end
96
94
  end
97
95
 
98
96
  context "ServerSide::Template.render" do
99
97
  specify "should raise a RuntimeError for an invalid template" do
100
98
  Template.reset
101
- proc {Template.render('invalid', binding)}.should_raise RuntimeError
99
+ proc {Template.render('invalid', binding)}.should raise_error(RuntimeError)
102
100
  end
103
101
 
104
102
  specify "should render an existing ad-hoc template" do
data/spec/xml_spec.rb ADDED
@@ -0,0 +1,75 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "A new XML representation" do
4
+ specify "should work with no arguments" do
5
+ xml = ServerSide::XML.new
6
+ xml.to_s.should == ''
7
+
8
+ xml.abc
9
+ xml.to_s.should == '<abc></abc>'
10
+ end
11
+
12
+ specify "should accept a tag name" do
13
+ xml = ServerSide::XML.new('def')
14
+ xml.to_s.should == '<def></def>'
15
+ end
16
+
17
+ specify "should accept attributes" do
18
+ xml = ServerSide::XML.new('a', :href => '/hello/dolly')
19
+ xml.to_s.should == '<a href="/hello/dolly"></a>'
20
+ end
21
+
22
+ specify "should accept a block and run it" do
23
+ xml = ServerSide::XML.new do |x|
24
+ x.abc do
25
+ x.def 123
26
+ end
27
+ end
28
+ xml.to_s.should == '<abc><def>123</def></abc>'
29
+ end
30
+ end
31
+
32
+ context "XML#instruct!" do
33
+ setup do
34
+ @xml = ServerSide::XML.new
35
+ end
36
+
37
+ specify "should add an XML instruction" do
38
+ @xml.instruct!
39
+ @xml.to_s.should =~ /^\<\?xml(.+)\?\>$/
40
+
41
+ @xml.to_s.should =~ /\s#{'version="1.0"'}/
42
+ @xml.to_s.should =~ /\s#{'encoding="UTF-8"'}/
43
+ end
44
+
45
+ specify "should accept attributes" do
46
+ @xml.instruct!(:something => 'XXX')
47
+ @xml.to_s.should == '<?xml something="XXX"?>'
48
+ end
49
+ end
50
+
51
+ context "XML instance methods" do
52
+ setup do
53
+ @xml = ServerSide::XML.new
54
+ end
55
+
56
+ specify "should escape values" do
57
+ @xml.x "&\"><"
58
+ @xml.to_s.should == "<x>&amp;&quot;&gt;&lt;</x>"
59
+ end
60
+
61
+ specify "should accept attributes" do
62
+ @xml.x({:z => '123'}, '')
63
+ @xml.to_s.should == '<x z="123"></x>'
64
+
65
+ @xml = ServerSide::XML.new
66
+ @xml.x({:z => '123'}, 'yyy')
67
+ @xml.to_s.should == '<x z="123">yyy</x>'
68
+ end
69
+
70
+ specify "should support subtags" do
71
+ h = {:name => 'abc', :category => 'def'}
72
+ @xml.item [:category, :name], h
73
+ @xml.to_s.should == '<item><category>def</category><name>abc</name></item>'
74
+ end
75
+ end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: serverside
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.4.1
7
- date: 2007-08-09 00:00:00 +03:00
6
+ version: 0.4.3
7
+ date: 2007-09-16 00:00:00 +03:00
8
8
  summary: Fast Ruby HTTP Server.
9
9
  require_paths:
10
10
  - lib
@@ -33,29 +33,34 @@ files:
33
33
  - README
34
34
  - Rakefile
35
35
  - bin/serverside
36
- - doc/rdoc
37
- - spec/daemon_spec.rb
38
36
  - spec/core_ext_spec.rb
39
- - spec/template_spec.rb
37
+ - spec/daemon_spec.rb
40
38
  - spec/http_spec.rb
39
+ - spec/js_spec.rb
40
+ - spec/request_spec.rb
41
+ - spec/response_spec.rb
42
+ - spec/spec_helper.rb
43
+ - spec/template_spec.rb
44
+ - spec/xml_spec.rb
41
45
  - lib/serverside
46
+ - lib/serverside.rb
47
+ - lib/serverside/cluster.rb
48
+ - lib/serverside/core_ext.rb
49
+ - lib/serverside/daemon.rb
42
50
  - lib/serverside/http
51
+ - lib/serverside/http.rb
52
+ - lib/serverside/js.rb
53
+ - lib/serverside/log.rb
54
+ - lib/serverside/template.rb
55
+ - lib/serverside/xml.rb
43
56
  - lib/serverside/http/caching.rb
44
57
  - lib/serverside/http/const.rb
45
58
  - lib/serverside/http/error.rb
46
59
  - lib/serverside/http/parsing.rb
60
+ - lib/serverside/http/request.rb
47
61
  - lib/serverside/http/response.rb
48
62
  - lib/serverside/http/server.rb
49
63
  - lib/serverside/http/static.rb
50
- - lib/serverside/http.rb
51
- - lib/serverside/xml.rb
52
- - lib/serverside/cluster.rb
53
- - lib/serverside/log.rb
54
- - lib/serverside/daemon.rb
55
- - lib/serverside/core_ext.rb
56
- - lib/serverside/template.rb
57
- - lib/serverside/js.rb
58
- - lib/serverside.rb
59
64
  test_files: []
60
65
 
61
66
  rdoc_options: