serverside 0.2.9 → 0.3.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.
- data/CHANGELOG +56 -0
- data/Rakefile +12 -52
- data/bin/serverside +1 -1
- data/lib/serverside/application.rb +2 -1
- data/lib/serverside/caching.rb +62 -50
- data/lib/serverside/controllers.rb +91 -0
- data/lib/serverside/core_ext.rb +6 -0
- data/lib/serverside/daemon.rb +25 -5
- data/lib/serverside/request.rb +17 -11
- data/lib/serverside/routing.rb +11 -10
- data/lib/serverside/server.rb +14 -6
- data/lib/serverside/static.rb +7 -18
- data/lib/serverside/template.rb +20 -12
- data/spec/caching_spec.rb +318 -0
- data/spec/cluster_spec.rb +140 -0
- data/{test/spec → spec}/connection_spec.rb +4 -4
- data/{test/spec/controller_spec.rb → spec/controllers_spec.rb} +15 -12
- data/{test/spec → spec}/core_ext_spec.rb +23 -18
- data/spec/daemon_spec.rb +99 -0
- data/{test/spec → spec}/request_spec.rb +45 -45
- data/spec/routing_spec.rb +240 -0
- data/spec/server_spec.rb +40 -0
- data/spec/static_spec.rb +279 -0
- data/spec/template_spec.rb +129 -0
- metadata +21 -35
- data/lib/serverside/controller.rb +0 -67
- data/test/functional/primitive_static_server_test.rb +0 -61
- data/test/functional/request_body_test.rb +0 -93
- data/test/functional/routing_server.rb +0 -14
- data/test/functional/routing_server_test.rb +0 -41
- data/test/functional/static_profile.rb +0 -17
- data/test/functional/static_rfuzz.rb +0 -31
- data/test/functional/static_server.rb +0 -7
- data/test/functional/static_server_test.rb +0 -31
- data/test/spec/caching_spec.rb +0 -139
- data/test/test_helper.rb +0 -2
- data/test/unit/cluster_test.rb +0 -129
- data/test/unit/connection_test.rb +0 -48
- data/test/unit/core_ext_test.rb +0 -46
- data/test/unit/daemon_test.rb +0 -75
- data/test/unit/request_test.rb +0 -278
- data/test/unit/routing_test.rb +0 -171
- data/test/unit/server_test.rb +0 -28
- data/test/unit/static_test.rb +0 -171
- data/test/unit/template_test.rb +0 -78
data/test/unit/request_test.rb
DELETED
@@ -1,278 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
class RequestTest < Test::Unit::TestCase
|
5
|
-
class DummyConnection
|
6
|
-
attr_reader :opened
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@opened = true
|
10
|
-
end
|
11
|
-
|
12
|
-
def close
|
13
|
-
@opened = false
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class DummyRequest2 < ServerSide::HTTP::Request
|
18
|
-
attr_accessor :count
|
19
|
-
|
20
|
-
def parse
|
21
|
-
@count = 1
|
22
|
-
end
|
23
|
-
|
24
|
-
def respond
|
25
|
-
@count += 1
|
26
|
-
@persistent = @count < 2
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_process
|
31
|
-
r = DummyRequest2.new(nil)
|
32
|
-
sleep 0.2
|
33
|
-
assert_equal false, r.process
|
34
|
-
assert_equal 2, r.count
|
35
|
-
assert_equal false, r.persistent
|
36
|
-
end
|
37
|
-
|
38
|
-
class DummyRequest3 < ServerSide::HTTP::Request
|
39
|
-
attr_accessor :parse_result, :respond_result
|
40
|
-
def parse; @parse_result; end
|
41
|
-
def respond; @respond_result; end
|
42
|
-
end
|
43
|
-
|
44
|
-
class ServerSide::HTTP::Request
|
45
|
-
attr_writer :socket, :persistent, :response_headers
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_process_result
|
49
|
-
r = DummyRequest3.new(nil)
|
50
|
-
r.parse_result = nil
|
51
|
-
r.persistent = true
|
52
|
-
assert_equal nil, r.process
|
53
|
-
r.parse_result = nil
|
54
|
-
r.respond_result = true
|
55
|
-
assert_equal nil, r.process
|
56
|
-
r.parse_result = {}
|
57
|
-
r.respond_result = nil
|
58
|
-
r.persistent = false
|
59
|
-
assert_equal false, r.process
|
60
|
-
r.parse_result = {}
|
61
|
-
r.respond_result = true
|
62
|
-
r.persistent = true
|
63
|
-
assert_equal true, r.process
|
64
|
-
r.parse_result = {}
|
65
|
-
r.persistent = 'hello'
|
66
|
-
assert_equal 'hello', r.process
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_parse_request_invalid
|
70
|
-
r = ServerSide::HTTP::Request.new(nil)
|
71
|
-
r.socket = StringIO.new('POST /test')
|
72
|
-
assert_nil r.parse
|
73
|
-
r.socket = StringIO.new('invalid string')
|
74
|
-
assert_nil r.parse
|
75
|
-
r.socket = StringIO.new('GET HTTP/1.1')
|
76
|
-
assert_nil r.parse
|
77
|
-
r.socket = StringIO.new('GET /test http')
|
78
|
-
assert_nil r.parse
|
79
|
-
r.socket = StringIO.new('GET /test HTTP')
|
80
|
-
assert_nil r.parse
|
81
|
-
r.socket = StringIO.new('GET /test HTTP/')
|
82
|
-
assert_nil r.parse
|
83
|
-
r.socket = StringIO.new('POST /test HTTP/1.1')
|
84
|
-
assert_nil r.parse
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_parse_request
|
88
|
-
r = ServerSide::HTTP::Request.new(nil)
|
89
|
-
r.socket = StringIO.new("POST /test HTTP/1.1\r\n\r\n")
|
90
|
-
assert_kind_of Hash, r.parse
|
91
|
-
assert_equal :post, r.method
|
92
|
-
assert_equal '/test', r.path
|
93
|
-
assert_nil r.query
|
94
|
-
assert_equal '1.1', r.version
|
95
|
-
assert_equal({}, r.parameters)
|
96
|
-
assert_equal({}, r.headers)
|
97
|
-
assert_equal({}, r.cookies)
|
98
|
-
assert_nil r.response_cookies
|
99
|
-
assert_equal true, r.persistent
|
100
|
-
|
101
|
-
# trailing slash in path
|
102
|
-
r = ServerSide::HTTP::Request.new(nil)
|
103
|
-
r.socket = StringIO.new("POST /test/asdf/qw/?time=24%20hours HTTP/1.1\r\n\r\n")
|
104
|
-
assert_kind_of Hash, r.parse
|
105
|
-
assert_equal :post, r.method
|
106
|
-
assert_equal '/test/asdf/qw', r.path
|
107
|
-
assert_equal 'time=24%20hours', r.query
|
108
|
-
assert_equal '1.1', r.version
|
109
|
-
assert_equal({:time => '24 hours'}, r.parameters)
|
110
|
-
assert_equal({}, r.headers)
|
111
|
-
assert_equal({}, r.cookies)
|
112
|
-
assert_nil r.response_cookies
|
113
|
-
assert_equal true, r.persistent
|
114
|
-
|
115
|
-
r.socket = StringIO.new("GET /cex?q=node_state HTTP/1.1\r\n\r\n")
|
116
|
-
assert_kind_of Hash, r.parse
|
117
|
-
assert_equal :get, r.method
|
118
|
-
assert_equal '/cex', r.path
|
119
|
-
assert_equal 'q=node_state', r.query
|
120
|
-
assert_equal({:q => 'node_state'}, r.parameters)
|
121
|
-
assert_equal({}, r.cookies)
|
122
|
-
assert_nil r.response_cookies
|
123
|
-
|
124
|
-
r.socket = StringIO.new("GET / HTTP/1.0\r\n\r\n")
|
125
|
-
assert_kind_of Hash, r.parse
|
126
|
-
assert_equal false, r.persistent
|
127
|
-
assert_equal({}, r.cookies)
|
128
|
-
assert_nil r.response_cookies
|
129
|
-
|
130
|
-
r.socket = StringIO.new("GET / HTTP/invalid\r\n\r\n")
|
131
|
-
assert_kind_of Hash, r.parse
|
132
|
-
assert_equal 'invalid', r.version
|
133
|
-
assert_equal false, r.persistent
|
134
|
-
|
135
|
-
r.socket = StringIO.new("GET / HTTP/1.1\r\nConnection: close\r\n\r\n")
|
136
|
-
assert_kind_of Hash, r.parse
|
137
|
-
assert_equal '1.1', r.version
|
138
|
-
assert_equal 'close', r.headers['Connection']
|
139
|
-
assert_equal false, r.persistent
|
140
|
-
|
141
|
-
# cookies
|
142
|
-
r.socket = StringIO.new("GET / HTTP/1.1\r\nConnection: close\r\nCookie: abc=1342; def=7%2f4\r\n\r\n")
|
143
|
-
assert_kind_of Hash, r.parse
|
144
|
-
assert_equal 'abc=1342; def=7%2f4', r.headers['Cookie']
|
145
|
-
assert_equal '1342', r.cookies[:abc]
|
146
|
-
assert_equal '7/4', r.cookies[:def]
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_send_response
|
150
|
-
r = ServerSide::HTTP::Request.new(nil)
|
151
|
-
# simple case
|
152
|
-
r.response_headers = {}
|
153
|
-
r.socket = StringIO.new
|
154
|
-
r.persistent = true
|
155
|
-
r.send_response(200, 'text', 'Hello there!')
|
156
|
-
r.socket.rewind
|
157
|
-
assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nContent-Type: text\r\nContent-Length: 12\r\n\r\nHello there!",
|
158
|
-
r.socket.read
|
159
|
-
|
160
|
-
# include content-length
|
161
|
-
r.response_headers = {}
|
162
|
-
r.socket = StringIO.new
|
163
|
-
r.persistent = true
|
164
|
-
r.send_response(404, 'text/html', '<h1>404!</h1>', 10) # incorrect length
|
165
|
-
r.socket.rewind
|
166
|
-
assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nContent-Type: text/html\r\nContent-Length: 10\r\n\r\n<h1>404!</h1>",
|
167
|
-
r.socket.read
|
168
|
-
|
169
|
-
# headers
|
170
|
-
r.response_headers = {}
|
171
|
-
r.socket = StringIO.new
|
172
|
-
r.persistent = true
|
173
|
-
r.send_response(404, 'text/html', '<h1>404!</h1>', nil, {'ETag' => 'xxyyzz'})
|
174
|
-
r.socket.rewind
|
175
|
-
assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nContent-Type: text/html\r\nETag: xxyyzz\r\nContent-Length: 13\r\n\r\n<h1>404!</h1>",
|
176
|
-
r.socket.read
|
177
|
-
|
178
|
-
# no body
|
179
|
-
r.response_headers = {}
|
180
|
-
r.socket = StringIO.new
|
181
|
-
r.persistent = true
|
182
|
-
r.send_response(404, 'text/html', nil, nil, {'Set-Cookie' => 'abc=123'})
|
183
|
-
r.socket.rewind
|
184
|
-
assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text/html\r\nSet-Cookie: abc=123\r\n\r\n",
|
185
|
-
r.socket.read
|
186
|
-
assert_equal false, r.persistent
|
187
|
-
|
188
|
-
# not persistent
|
189
|
-
r.response_headers = {}
|
190
|
-
r.socket = StringIO.new
|
191
|
-
r.persistent = false
|
192
|
-
r.send_response(200, 'text', 'Hello there!')
|
193
|
-
r.socket.rewind
|
194
|
-
assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text\r\nContent-Length: 12\r\n\r\nHello there!",
|
195
|
-
r.socket.read
|
196
|
-
|
197
|
-
# socket error
|
198
|
-
r.response_headers = {}
|
199
|
-
r.socket = nil
|
200
|
-
r.persistent = true
|
201
|
-
assert_nothing_raised {r.send_response(200, 'text', 'Hello there!')}
|
202
|
-
assert_equal false, r.persistent
|
203
|
-
end
|
204
|
-
|
205
|
-
def test_stream
|
206
|
-
r = ServerSide::HTTP::Request.new(nil)
|
207
|
-
r.socket = StringIO.new
|
208
|
-
r.stream 'hey there'
|
209
|
-
r.socket.rewind
|
210
|
-
assert_equal 'hey there', r.socket.read
|
211
|
-
|
212
|
-
r.socket = StringIO.new
|
213
|
-
r.persistent = true
|
214
|
-
r.send_response(404, 'text/html', nil, nil, {'Set-Cookie' => 'abc=123'})
|
215
|
-
r.stream('hey there')
|
216
|
-
r.socket.rewind
|
217
|
-
assert_equal "HTTP/1.1 404\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text/html\r\nSet-Cookie: abc=123\r\n\r\nhey there",
|
218
|
-
r.socket.read
|
219
|
-
end
|
220
|
-
|
221
|
-
def test_redirect
|
222
|
-
r = ServerSide::HTTP::Request.new(nil)
|
223
|
-
r.socket = StringIO.new
|
224
|
-
r.redirect('http://mau.com/132')
|
225
|
-
r.socket.rewind
|
226
|
-
assert_equal "HTTP/1.1 302\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nLocation: http://mau.com/132\r\n\r\n", r.socket.read
|
227
|
-
|
228
|
-
r.response_headers = {}
|
229
|
-
r.socket = StringIO.new
|
230
|
-
r.redirect('http://www.google.com/search?q=meaning%20of%20life', true)
|
231
|
-
r.socket.rewind
|
232
|
-
assert_equal "HTTP/1.1 301\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nLocation: http://www.google.com/search?q=meaning%20of%20life\r\n\r\n", r.socket.read
|
233
|
-
end
|
234
|
-
|
235
|
-
def test_set_cookie
|
236
|
-
r = ServerSide::HTTP::Request.new(nil)
|
237
|
-
r.socket = StringIO.new
|
238
|
-
t = Time.now + 360
|
239
|
-
r.set_cookie(:session, "ABCDEFG", t)
|
240
|
-
assert_equal "Set-Cookie: session=ABCDEFG; path=/; expires=#{t.rfc2822}\r\n", r.response_cookies
|
241
|
-
r.send_response(200, 'text', 'Hi!')
|
242
|
-
r.socket.rewind
|
243
|
-
assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text\r\nSet-Cookie: session=ABCDEFG; path=/; expires=#{t.rfc2822}\r\nContent-Length: 3\r\n\r\nHi!", r.socket.read
|
244
|
-
end
|
245
|
-
|
246
|
-
def test_delete_cookie
|
247
|
-
r = ServerSide::HTTP::Request.new(nil)
|
248
|
-
r.socket = StringIO.new
|
249
|
-
r.delete_cookie(:session)
|
250
|
-
assert_equal "Set-Cookie: session=; path=/; expires=#{Time.at(0).rfc2822}\r\n", r.response_cookies
|
251
|
-
r.send_response(200, 'text', 'Hi!')
|
252
|
-
r.socket.rewind
|
253
|
-
assert_equal "HTTP/1.1 200\r\nDate: #{Time.now.httpdate}\r\nConnection: close\r\nContent-Type: text\r\nSet-Cookie: session=; path=/; expires=#{Time.at(0).rfc2822}\r\nContent-Length: 3\r\n\r\nHi!", r.socket.read
|
254
|
-
end
|
255
|
-
|
256
|
-
def test_response_headers
|
257
|
-
r = ServerSide::HTTP::Request.new(nil)
|
258
|
-
r.socket = StringIO.new
|
259
|
-
assert_equal({}, r.response_headers)
|
260
|
-
r.response_headers = {'A' => '1', 'B' => 2}
|
261
|
-
r.send_response(200, 'text', 'Hi!')
|
262
|
-
r.socket.rewind
|
263
|
-
resp = r.socket.read
|
264
|
-
assert_not_nil resp.match("A: 1\r\n")
|
265
|
-
assert_not_nil resp.match("B: 2\r\n")
|
266
|
-
|
267
|
-
r.response_headers = {}
|
268
|
-
r.socket = StringIO.new
|
269
|
-
assert_equal({}, r.response_headers)
|
270
|
-
r.response_headers = {'D' => '1', 'E' => 2}
|
271
|
-
r.send_response(200, 'text', 'Hi!', nil, {'F' => 3})
|
272
|
-
r.socket.rewind
|
273
|
-
resp = r.socket.read
|
274
|
-
assert_not_nil resp.match("D: 1\r\n")
|
275
|
-
assert_not_nil resp.match("E: 2\r\n")
|
276
|
-
assert_not_nil resp.match("F: 3\r\n")
|
277
|
-
end
|
278
|
-
end
|
data/test/unit/routing_test.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
class ServerSide::Router
|
5
|
-
attr_accessor :t, :parameters
|
6
|
-
|
7
|
-
def self.rules
|
8
|
-
@@rules
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.remove_rules
|
12
|
-
@@rules = nil
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.reset_rules
|
16
|
-
@@rules = []
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.reset_respond
|
20
|
-
define_method(:respond) {nil}
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class RoutingTest < Test::Unit::TestCase
|
25
|
-
R = ServerSide::Router
|
26
|
-
|
27
|
-
def test_has_routes?
|
28
|
-
R.remove_rules
|
29
|
-
assert_nil R.has_routes?
|
30
|
-
R.reset_rules
|
31
|
-
assert_equal false, R.has_routes?
|
32
|
-
R.route('/controller/:action/:id') {}
|
33
|
-
assert_equal true, R.has_routes?
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_route
|
37
|
-
l1 = lambda {1 + 1}
|
38
|
-
R.reset_rules
|
39
|
-
R.route('/controller/:action/:id', &l1)
|
40
|
-
assert_equal 1, R.rules.length
|
41
|
-
assert_equal({:path => '/controller/:action/:id'}, R.rules[0][0])
|
42
|
-
assert_equal l1, R.rules[0][1]
|
43
|
-
|
44
|
-
l2 = lambda {2 + 2}
|
45
|
-
R.route(:host => '^static\..+', &l2)
|
46
|
-
assert_equal 2, R.rules.length
|
47
|
-
assert_equal({:host => '^static\..+'}, R.rules[0][0])
|
48
|
-
assert_equal l2, R.rules[0][1]
|
49
|
-
assert_equal({:path => '/controller/:action/:id'}, R.rules[1][0])
|
50
|
-
assert_equal l1, R.rules[1][1]
|
51
|
-
|
52
|
-
l3 = lambda {3 + 3}
|
53
|
-
l4 = lambda {4 + 4}
|
54
|
-
|
55
|
-
R.route(l3, &l4)
|
56
|
-
assert_equal 3, R.rules.length
|
57
|
-
assert_equal l3, R.rules[0][0]
|
58
|
-
assert_equal l4, R.rules[0][1]
|
59
|
-
assert_equal({:host => '^static\..+'}, R.rules[1][0])
|
60
|
-
assert_equal l2, R.rules[1][1]
|
61
|
-
assert_equal({:path => '/controller/:action/:id'}, R.rules[2][0])
|
62
|
-
assert_equal l1, R.rules[2][1]
|
63
|
-
end
|
64
|
-
|
65
|
-
def test_compile_rules
|
66
|
-
R.reset_rules
|
67
|
-
R.reset_respond
|
68
|
-
|
69
|
-
assert_equal nil, R.new(StringIO.new).respond
|
70
|
-
R.rules << [{:t => 'abc'}, lambda{1}]
|
71
|
-
R.rules << [{:t => 'def'}, lambda{2}]
|
72
|
-
R.default_route {3}
|
73
|
-
R.compile_rules
|
74
|
-
r = R.new(StringIO.new)
|
75
|
-
r.t = 'abc'
|
76
|
-
assert_equal 1, r.respond
|
77
|
-
r.t = 'def'
|
78
|
-
assert_equal 2, r.respond
|
79
|
-
r.t = ''
|
80
|
-
assert_equal 3, r.respond
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_rule_to_statement
|
84
|
-
l1 = lambda {1 + 1}
|
85
|
-
l2 = lambda {2 + 2}
|
86
|
-
s = R.rule_to_statement(l1, l2)
|
87
|
-
assert_equal "return #{l2.proc_tag} if #{l1.proc_tag}\n" ,s
|
88
|
-
r = R.new(StringIO.new)
|
89
|
-
assert_equal true, r.respond_to?(l1.proc_tag)
|
90
|
-
assert_equal true, r.respond_to?(l2.proc_tag)
|
91
|
-
|
92
|
-
l3 = lambda {3 + 3}
|
93
|
-
s = R.rule_to_statement({:path => '/.*'}, l3)
|
94
|
-
assert_not_nil s =~ /^return\s#{l3.proc_tag}\sif\s\(@path\s=~\s(.*)\)\n$/, s
|
95
|
-
assert_equal /\/.*/, eval("R::#{$1}")
|
96
|
-
assert_equal true, r.respond_to?(l3.proc_tag)
|
97
|
-
|
98
|
-
l4 = lambda {4 + 4}
|
99
|
-
s = R.rule_to_statement({:path => '/controller', :host => 'static'}, l4)
|
100
|
-
assert_not_nil s =~ /^return\s#{l4.proc_tag}\sif\s\(.+\)&&\(.+\)\n$/
|
101
|
-
assert_not_nil s =~ /\(@path\s=~\s([^\)]+)\)/
|
102
|
-
assert_equal /\/controller/, eval("R::#{$1}")
|
103
|
-
assert_not_nil s =~ /\(@host\s=~\s([^\)]+)\)/
|
104
|
-
assert_equal /static/, eval("R::#{$1}")
|
105
|
-
assert_equal true, r.respond_to?(l4.proc_tag)
|
106
|
-
|
107
|
-
l5 = lambda {5 + 5}
|
108
|
-
s = R.rule_to_statement({:path => ['/x', '/y']}, l5)
|
109
|
-
assert_not_nil s =~ /^return\s#{l5.proc_tag}\sif\s\(\(@path\s=~\s(.*)\)\|\|\(@path\s=~\s(.*)\)\)\n$/
|
110
|
-
assert_equal /\/x/, eval("R::#{$1}")
|
111
|
-
assert_equal /\/y/, eval("R::#{$2}")
|
112
|
-
assert_equal true, r.respond_to?(l5.proc_tag)
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_condition_part
|
116
|
-
s = R.condition_part(:t, 'abc')
|
117
|
-
assert_not_nil s =~ /^\(@t\s=~\s(.*)\)$/
|
118
|
-
assert_equal /abc/, eval("R::#{$1}")
|
119
|
-
|
120
|
-
s = R.condition_part(:t, ':action/:id')
|
121
|
-
assert_not_nil s =~ /^\((.*)\)$/
|
122
|
-
tag = $1
|
123
|
-
r = R.new(StringIO.new)
|
124
|
-
assert_equal true, r.respond_to?(tag)
|
125
|
-
r.parameters = {}
|
126
|
-
r.t = 'abc'
|
127
|
-
assert_equal false, r.send(tag)
|
128
|
-
r.t = 'show/16'
|
129
|
-
assert_equal true, r.send(tag)
|
130
|
-
assert_equal 'show', r.parameters[:action]
|
131
|
-
assert_equal '16', r.parameters[:id]
|
132
|
-
end
|
133
|
-
|
134
|
-
def test_define_proc
|
135
|
-
l1 = lambda {1 + 1}
|
136
|
-
tag = R.define_proc(&l1)
|
137
|
-
assert_kind_of Symbol, tag
|
138
|
-
assert_equal l1.proc_tag.to_sym, tag
|
139
|
-
r = R.new(StringIO.new)
|
140
|
-
assert 2, r.send(tag)
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_cache_constant
|
144
|
-
c = rand(100000)
|
145
|
-
tag = R.cache_constant(c)
|
146
|
-
assert_kind_of String, tag
|
147
|
-
assert_equal c.const_tag, tag
|
148
|
-
assert_equal c, eval("R::#{tag}")
|
149
|
-
end
|
150
|
-
|
151
|
-
def test_default_route
|
152
|
-
R.default_route {'mau m'}
|
153
|
-
assert_equal 'mau m', R.new(StringIO.new).default_handler
|
154
|
-
|
155
|
-
R.default_route {654321}
|
156
|
-
assert_equal 654321, R.new(StringIO.new).default_handler
|
157
|
-
end
|
158
|
-
|
159
|
-
def test_serverside_route
|
160
|
-
R.reset_rules
|
161
|
-
ServerSide::Router.route(:path => 'abc') {1 + 1}
|
162
|
-
assert_equal 1, R.rules.length
|
163
|
-
assert_equal({:path => 'abc'}, R.rules[0][0])
|
164
|
-
assert_equal 2, R.rules[0][1].call
|
165
|
-
end
|
166
|
-
|
167
|
-
def test_serverside_default_route
|
168
|
-
ServerSide::Router.default_route {1234}
|
169
|
-
assert_equal 1234, R.new(StringIO.new).default_handler
|
170
|
-
end
|
171
|
-
end
|
data/test/unit/server_test.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
class ServerTest < Test::Unit::TestCase
|
5
|
-
class DummyRequest < ServerSide::HTTP::Request
|
6
|
-
def respond
|
7
|
-
@socket << "HTTP/1.1 200\r\nContent-Length: 9\r\n\r\nHi there!"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_server_creation
|
12
|
-
t = Thread.new do
|
13
|
-
begin
|
14
|
-
ServerSide::HTTP::Server.new('0.0.0.0', 17543, DummyRequest)
|
15
|
-
rescue => e
|
16
|
-
puts e.message
|
17
|
-
puts e.backtrace.first
|
18
|
-
end
|
19
|
-
end
|
20
|
-
sleep 0.1
|
21
|
-
|
22
|
-
h = Net::HTTP.new('localhost', 17543)
|
23
|
-
resp, data = h.get('/', nil)
|
24
|
-
assert_equal 200, resp.code.to_i
|
25
|
-
assert_equal 'Hi there!', data
|
26
|
-
t.exit
|
27
|
-
end
|
28
|
-
end
|
data/test/unit/static_test.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'stringio'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
class StaticTest < Test::Unit::TestCase
|
6
|
-
class Dummy < ServerSide::HTTP::Request
|
7
|
-
def self.static_files
|
8
|
-
@@static_files
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.mime_types
|
12
|
-
@@mime_types
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_accessor :path, :socket, :headers
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
super(nil)
|
19
|
-
@headers = {}
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_cache
|
24
|
-
assert_kind_of Hash, Dummy.static_files
|
25
|
-
Dummy.static_files.clear
|
26
|
-
c = Dummy.new
|
27
|
-
c.socket = StringIO.new
|
28
|
-
assert_nil Dummy.static_files[__FILE__]
|
29
|
-
c.serve_file(__FILE__)
|
30
|
-
cache = Dummy.static_files[__FILE__]
|
31
|
-
assert_not_nil cache
|
32
|
-
stat = File.stat(__FILE__)
|
33
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
34
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
35
|
-
assert_equal etag, cache[0]
|
36
|
-
assert_equal IO.read(__FILE__), cache[1]
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_mime_types
|
40
|
-
assert_kind_of Hash, Dummy.mime_types
|
41
|
-
assert_equal 'text/plain', Dummy.mime_types['.rb']
|
42
|
-
assert_equal 'text/plain', Dummy.mime_types['.invalid']
|
43
|
-
assert_equal 'text/html', Dummy.mime_types['.html']
|
44
|
-
assert_equal 'text/css', Dummy.mime_types['.css']
|
45
|
-
assert_equal 'text/javascript', Dummy.mime_types['.js']
|
46
|
-
assert_equal 'image/gif', Dummy.mime_types['.gif']
|
47
|
-
assert_equal 'image/jpeg', Dummy.mime_types['.jpg']
|
48
|
-
assert_equal 'image/jpeg', Dummy.mime_types['.jpeg']
|
49
|
-
assert_equal 'image/png', Dummy.mime_types['.png']
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_serve_file_normal
|
53
|
-
c = Dummy.new
|
54
|
-
c.socket = StringIO.new
|
55
|
-
c.serve_file(__FILE__)
|
56
|
-
c.socket.rewind
|
57
|
-
resp = c.socket.read
|
58
|
-
|
59
|
-
assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
|
60
|
-
fc = IO.read(__FILE__)
|
61
|
-
stat = File.stat(__FILE__)
|
62
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
63
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
64
|
-
assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
|
65
|
-
assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
|
66
|
-
assert_equal stat.size.to_s,
|
67
|
-
/Content-Length:\s(.*)\r\n/.match(resp)[1]
|
68
|
-
end
|
69
|
-
|
70
|
-
def test_serve_file_etags
|
71
|
-
c = Dummy.new
|
72
|
-
c.socket = StringIO.new
|
73
|
-
Dummy.static_files.clear
|
74
|
-
c.serve_file(__FILE__)
|
75
|
-
c.socket.rewind
|
76
|
-
resp = c.socket.read
|
77
|
-
|
78
|
-
# normal response
|
79
|
-
assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
|
80
|
-
fc = IO.read(__FILE__)
|
81
|
-
stat = File.stat(__FILE__)
|
82
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
83
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
84
|
-
assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
|
85
|
-
assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
|
86
|
-
assert_equal stat.size.to_s,
|
87
|
-
/Content-Length:\s(.*)\r\n/.match(resp)[1]
|
88
|
-
|
89
|
-
c.socket = StringIO.new
|
90
|
-
c.headers[ServerSide::Static::IF_NONE_MATCH] = "\"#{etag}\""
|
91
|
-
c.serve_file(__FILE__)
|
92
|
-
c.socket.rewind
|
93
|
-
resp = c.socket.read
|
94
|
-
|
95
|
-
# not modified response
|
96
|
-
assert_equal '304 Not Modified', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
|
97
|
-
fc = IO.read(__FILE__)
|
98
|
-
stat = File.stat(__FILE__)
|
99
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
100
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
101
|
-
assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
|
102
|
-
assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
|
103
|
-
|
104
|
-
FileUtils.touch(__FILE__)
|
105
|
-
c.socket = StringIO.new
|
106
|
-
c.headers[ServerSide::Static::IF_NONE_MATCH] = etag
|
107
|
-
c.serve_file(__FILE__)
|
108
|
-
c.socket.rewind
|
109
|
-
resp = c.socket.read
|
110
|
-
|
111
|
-
# modified response
|
112
|
-
assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
|
113
|
-
fc = IO.read(__FILE__)
|
114
|
-
stat = File.stat(__FILE__)
|
115
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
116
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
117
|
-
assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
|
118
|
-
assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
|
119
|
-
assert_equal stat.size.to_s,
|
120
|
-
/Content-Length:\s(.*)\r\n/.match(resp)[1]
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_serve_dir
|
124
|
-
dir = File.dirname(__FILE__)
|
125
|
-
|
126
|
-
c = Dummy.new
|
127
|
-
c.socket = StringIO.new
|
128
|
-
Dummy.static_files.clear
|
129
|
-
c.path = dir
|
130
|
-
c.serve_dir(dir)
|
131
|
-
c.socket.rewind
|
132
|
-
resp = c.socket.read
|
133
|
-
|
134
|
-
Dir.entries(dir).each do |fn|
|
135
|
-
next if fn =~ /^\./
|
136
|
-
assert_not_nil resp =~ /<a href="#{dir/fn}">(#{fn})<\/a>/
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def test_serve_static
|
141
|
-
dir = File.dirname(__FILE__)
|
142
|
-
|
143
|
-
c = Dummy.new
|
144
|
-
c.socket = StringIO.new
|
145
|
-
c.path = dir
|
146
|
-
c.serve_static(dir)
|
147
|
-
c.socket.rewind
|
148
|
-
resp = c.socket.read
|
149
|
-
|
150
|
-
Dir.entries(dir).each do |fn|
|
151
|
-
next if fn =~ /^\./
|
152
|
-
assert_not_nil resp =~ /<a href="#{dir/fn}">(#{fn})<\/a>/
|
153
|
-
end
|
154
|
-
|
155
|
-
c.socket = StringIO.new
|
156
|
-
c.serve_file(__FILE__)
|
157
|
-
c.socket.rewind
|
158
|
-
resp = c.socket.read
|
159
|
-
|
160
|
-
# normal response
|
161
|
-
assert_equal '200', /HTTP\/1.1\s(.*)\r\n/.match(resp)[1]
|
162
|
-
fc = IO.read(__FILE__)
|
163
|
-
stat = File.stat(__FILE__)
|
164
|
-
etag = (ServerSide::Static::ETAG_FORMAT %
|
165
|
-
[stat.mtime.to_i, stat.size, stat.ino])
|
166
|
-
assert_not_nil resp =~ /ETag:\s"#{etag}"\r\n/
|
167
|
-
assert_not_nil resp =~ /Cache-Control:\smax-age=#{ServerSide::HTTP::Caching::DEFAULT_MAX_AGE}\r\n/
|
168
|
-
assert_equal stat.size.to_s,
|
169
|
-
/Content-Length:\s(.*)\r\n/.match(resp)[1]
|
170
|
-
end
|
171
|
-
end
|