rufus-sixjo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +87 -0
- data/lib/rufus/sixjo.rb +353 -0
- data/test/ft_0_simple.rb +52 -0
- data/test/ft_1_helpers.rb +46 -0
- data/test/ft_2_redirect.rb +37 -0
- data/test/ft_3_erb.rb +71 -0
- data/test/ft_4_configure.rb +61 -0
- data/test/ft_5_put.rb +97 -0
- data/test/test.rb +8 -0
- data/test/testmixins.rb +40 -0
- metadata +72 -0
data/README.txt
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
|
2
|
+
= 'rufus-sixjo'
|
3
|
+
|
4
|
+
== what is it ?
|
5
|
+
|
6
|
+
A 'Rack application' for
|
7
|
+
|
8
|
+
|
9
|
+
== features
|
10
|
+
|
11
|
+
not many.
|
12
|
+
|
13
|
+
|
14
|
+
== getting it
|
15
|
+
|
16
|
+
sudo gem install -y rufus-sixjo
|
17
|
+
|
18
|
+
or download[http://rubyforge.org/frs/?group_id=4812] it from RubyForge.
|
19
|
+
|
20
|
+
|
21
|
+
== usage
|
22
|
+
|
23
|
+
see under the examples/ directory : http://github.com/jmettraux/rufus-sixjo/tree/master/examples
|
24
|
+
|
25
|
+
It goes like :
|
26
|
+
|
27
|
+
require 'rubygems'
|
28
|
+
require 'rufus/sixjo' # gem 'rufus-sixjo'
|
29
|
+
|
30
|
+
module ExampleOne
|
31
|
+
|
32
|
+
extend Rufus::Sixjo
|
33
|
+
|
34
|
+
get '/toto' do
|
35
|
+
"nada at #{request.path_info}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
app = Rack::Builder.new do
|
40
|
+
|
41
|
+
use Rack::CommonLogger
|
42
|
+
use Rack::ShowExceptions
|
43
|
+
run ExampleOne.new_sixjo_rack_app(nil)
|
44
|
+
end
|
45
|
+
|
46
|
+
Rack::Handler::Mongrel.run app, :Port => 2042
|
47
|
+
|
48
|
+
|
49
|
+
== dependencies
|
50
|
+
|
51
|
+
the 'rack' gem
|
52
|
+
|
53
|
+
|
54
|
+
== mailing list
|
55
|
+
|
56
|
+
On the Rufus-Ruby list[http://groups.google.com/group/rufus-ruby] :
|
57
|
+
|
58
|
+
http://groups.google.com/group/rufus-ruby
|
59
|
+
|
60
|
+
|
61
|
+
== issue tracker
|
62
|
+
|
63
|
+
http://rubyforge.org/tracker/?atid=18584&group_id=4812&func=browse
|
64
|
+
|
65
|
+
|
66
|
+
== source
|
67
|
+
|
68
|
+
http://github.com/jmettraux/rufus-sixjo
|
69
|
+
|
70
|
+
git clone git://github.com/jmettraux/rufus-sixjo.git
|
71
|
+
|
72
|
+
|
73
|
+
== author
|
74
|
+
|
75
|
+
John Mettraux, jmettraux@gmail.com,
|
76
|
+
http://jmettraux.wordpress.com
|
77
|
+
|
78
|
+
|
79
|
+
== the rest of Rufus
|
80
|
+
|
81
|
+
http://rufus.rubyforge.org
|
82
|
+
|
83
|
+
|
84
|
+
== license
|
85
|
+
|
86
|
+
MIT
|
87
|
+
|
data/lib/rufus/sixjo.rb
ADDED
@@ -0,0 +1,353 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2008, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
#
|
24
|
+
|
25
|
+
#
|
26
|
+
# "made in Japan"
|
27
|
+
#
|
28
|
+
|
29
|
+
require 'erb'
|
30
|
+
require 'rack'
|
31
|
+
|
32
|
+
|
33
|
+
class Rack::Request
|
34
|
+
|
35
|
+
def content
|
36
|
+
@env['rack.request.form_vars']
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Rack::Response
|
41
|
+
|
42
|
+
def location= (l)
|
43
|
+
header['Location'] = l
|
44
|
+
end
|
45
|
+
def content_type= (t)
|
46
|
+
header['Content-type'] = t
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
module Rufus
|
52
|
+
|
53
|
+
module Sixjo
|
54
|
+
|
55
|
+
VERSION = "0.1.0"
|
56
|
+
|
57
|
+
#
|
58
|
+
# Sixjo's Rack app
|
59
|
+
#
|
60
|
+
class App
|
61
|
+
|
62
|
+
attr_reader :environment
|
63
|
+
|
64
|
+
def initialize (next_app, routes, helpers, configures, options)
|
65
|
+
|
66
|
+
@next_app = next_app
|
67
|
+
@routes = routes || [] # the 'no route' case is rather useless...
|
68
|
+
@helpers = helpers || []
|
69
|
+
|
70
|
+
#@prefix = options[:prefix] || ''
|
71
|
+
#@rprefix = Regexp.new(@prefix)
|
72
|
+
|
73
|
+
@environment = options[:environment] || 'development'
|
74
|
+
@environment = @environment.to_s
|
75
|
+
|
76
|
+
#
|
77
|
+
# run the configure blocks
|
78
|
+
|
79
|
+
(configures || []).each do |envs, block|
|
80
|
+
instance_eval(&block) if envs.empty? or envs.include?(@environment)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def application
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def call (env)
|
89
|
+
|
90
|
+
block = nil
|
91
|
+
|
92
|
+
begin
|
93
|
+
block = lookup_block(env)
|
94
|
+
rescue => e
|
95
|
+
#puts e
|
96
|
+
#puts e.backtrace
|
97
|
+
return [ 400, {}, e.to_s ]
|
98
|
+
end
|
99
|
+
|
100
|
+
if block
|
101
|
+
Context.service(self, block, @helpers, env)
|
102
|
+
elsif @next_app
|
103
|
+
@next_app.call(env)
|
104
|
+
else
|
105
|
+
[ 404, {}, [ "not found #{env['PATH_INFO']}" ] ]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
protected
|
110
|
+
|
111
|
+
H_METHODS = [ 'GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS' ]
|
112
|
+
R_METHOD = /_method=(put|delete|PUT|DELETE)/
|
113
|
+
R_MULTIPART = /^multipart\/form-data;/
|
114
|
+
|
115
|
+
def lookup_block (env)
|
116
|
+
|
117
|
+
request_method = get_request_method(env)
|
118
|
+
|
119
|
+
@routes.each do |verb, route, block|
|
120
|
+
next unless request_method == verb
|
121
|
+
next unless route.match?(env)
|
122
|
+
return block
|
123
|
+
end
|
124
|
+
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_request_method (env)
|
129
|
+
|
130
|
+
rm = env['X-HTTP-Method-Override'] || env['REQUEST_METHOD']
|
131
|
+
rm = rm.upcase
|
132
|
+
|
133
|
+
#puts env.inspect
|
134
|
+
|
135
|
+
if rm == 'POST'
|
136
|
+
md = R_METHOD.match(env['QUERY_STRING'])
|
137
|
+
rm = md[1].upcase if md
|
138
|
+
|
139
|
+
ct = env['CONTENT_TYPE']
|
140
|
+
|
141
|
+
if ct and R_MULTIPART.match(ct)
|
142
|
+
request = Rack::Request.new(env)
|
143
|
+
env['_rack_request'] = request # no need to rebuild later
|
144
|
+
hidden_method = request.POST['_method']
|
145
|
+
rm = hidden_method.upcase if hidden_method
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
raise "unknown HTTP method '#{rm}'" unless H_METHODS.include?(rm)
|
150
|
+
|
151
|
+
rm
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# ERB views
|
157
|
+
#
|
158
|
+
module Erb
|
159
|
+
|
160
|
+
#
|
161
|
+
# a local [context] for ERB views
|
162
|
+
#
|
163
|
+
class Local
|
164
|
+
|
165
|
+
def initialize (context, locals)
|
166
|
+
@context = context
|
167
|
+
@locals = locals
|
168
|
+
end
|
169
|
+
|
170
|
+
def method_missing (m, *args)
|
171
|
+
|
172
|
+
l = @locals[m.to_sym]
|
173
|
+
return l if l != nil
|
174
|
+
|
175
|
+
@context.send(m, *args)
|
176
|
+
end
|
177
|
+
|
178
|
+
#def application; @context.application; end
|
179
|
+
#def request; @context.request; end
|
180
|
+
#def response; @context.response; end
|
181
|
+
|
182
|
+
def get_binding
|
183
|
+
binding
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def erb (template, options = {})
|
188
|
+
|
189
|
+
content = File.open("views/#{template}.erb").read
|
190
|
+
|
191
|
+
l = options[:locals]
|
192
|
+
l = Local.new(self, l || {}) unless l.is_a?(Local)
|
193
|
+
|
194
|
+
::ERB.new(content).result(l.get_binding)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
#
|
199
|
+
# The context in which an HTTP request is handled
|
200
|
+
#
|
201
|
+
class Context
|
202
|
+
|
203
|
+
include Erb
|
204
|
+
|
205
|
+
def metaclass
|
206
|
+
class << self
|
207
|
+
self
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
attr_reader :application
|
212
|
+
attr_reader :request, :response
|
213
|
+
|
214
|
+
def initialize (app, env)
|
215
|
+
|
216
|
+
@application = app
|
217
|
+
@request = env.delete('_rack_request') || Rack::Request.new(env)
|
218
|
+
@response = Rack::Response.new
|
219
|
+
|
220
|
+
@params = @request.params.merge(@request.env['_ROUTE_PARAMS'])
|
221
|
+
@params = @params.inject({}) { |r, (k, v)| r[k.to_sym] = v; r }
|
222
|
+
end
|
223
|
+
|
224
|
+
def self.service (app, block, helpers, env)
|
225
|
+
|
226
|
+
r = self.new(app, env)
|
227
|
+
|
228
|
+
helpers.each { |h| r.instance_eval &h }
|
229
|
+
|
230
|
+
r.metaclass.instance_eval { define_method :call, &block }
|
231
|
+
|
232
|
+
begin
|
233
|
+
|
234
|
+
caught = catch :done do
|
235
|
+
r.response.body = r.call || []
|
236
|
+
nil
|
237
|
+
end
|
238
|
+
|
239
|
+
if caught
|
240
|
+
#puts caught.inspect
|
241
|
+
r.response.status = caught[0]
|
242
|
+
r.response.body = caught[1]
|
243
|
+
end
|
244
|
+
|
245
|
+
rescue Exception => e
|
246
|
+
|
247
|
+
r.response.status = 500
|
248
|
+
r.response.content_type = 'text/plain'
|
249
|
+
r.response.body = e.to_s + "\n" + e.backtrace.join("\n")
|
250
|
+
end
|
251
|
+
|
252
|
+
r.response.finish
|
253
|
+
end
|
254
|
+
|
255
|
+
def params
|
256
|
+
@params
|
257
|
+
end
|
258
|
+
|
259
|
+
def redirect (path, status=303, body=nil)
|
260
|
+
@response.status = status
|
261
|
+
@response.location = path
|
262
|
+
@response.body = body || "#{status} redirecting to #{path}"
|
263
|
+
throw :done
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
#
|
268
|
+
# Wrapping all the details about route.match?(path) here...
|
269
|
+
#
|
270
|
+
class Route
|
271
|
+
|
272
|
+
C_CHAR = '[^/?:,&#\.]'
|
273
|
+
R_PARAM = /:(#{C_CHAR}+)/ # capturing route params
|
274
|
+
R_FORMAT = /\.(#{C_CHAR}+)$/ # capturing the resource/file format
|
275
|
+
|
276
|
+
def initialize (route, options)
|
277
|
+
|
278
|
+
@param_keys = []
|
279
|
+
|
280
|
+
@regex = route.gsub(R_PARAM) do
|
281
|
+
@param_keys << $1.to_sym
|
282
|
+
"(#{C_CHAR}+)" # ready to capture param values
|
283
|
+
end
|
284
|
+
|
285
|
+
@regex = /^#{@regex}(?:\.(#{C_CHAR}+))?$/
|
286
|
+
|
287
|
+
# TODO : do something with the options :agent, :accept, ...
|
288
|
+
end
|
289
|
+
|
290
|
+
def match? (env)
|
291
|
+
|
292
|
+
m = env['PATH_INFO'].match(@regex)
|
293
|
+
|
294
|
+
return false unless m
|
295
|
+
|
296
|
+
values = m.to_a[1..-1]
|
297
|
+
params = @param_keys.zip(values).inject({}) { |r, (k, v)| r[k] = v; r }
|
298
|
+
|
299
|
+
env['_ROUTE_PARAMS'] = params
|
300
|
+
|
301
|
+
env['_FORMAT'] = values.last if values.length > @param_keys.length
|
302
|
+
|
303
|
+
true
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
#--
|
308
|
+
# the methods for registering the routes
|
309
|
+
#++
|
310
|
+
[ :post, :get, :put, :delete ].each do |v|
|
311
|
+
module_eval <<-EOS
|
312
|
+
def #{v} (rt, opts={}, &blk)
|
313
|
+
(@routes ||= []) << [ '#{v.to_s.upcase}', Route.new(rt, opts), blk ]
|
314
|
+
end
|
315
|
+
EOS
|
316
|
+
end
|
317
|
+
|
318
|
+
#
|
319
|
+
# for example :
|
320
|
+
#
|
321
|
+
# helpers do
|
322
|
+
# def hello
|
323
|
+
# "hello #{params['who']}"
|
324
|
+
# end
|
325
|
+
# end
|
326
|
+
#
|
327
|
+
def helpers (&block)
|
328
|
+
|
329
|
+
(@helpers ||= []) << block
|
330
|
+
end
|
331
|
+
|
332
|
+
#
|
333
|
+
# Code in the 'configure' block will be run inside the application
|
334
|
+
# instance.
|
335
|
+
#
|
336
|
+
def configure (*envs, &block)
|
337
|
+
|
338
|
+
(@configures ||= []) << [ envs.collect { |e| e.to_s }, block ]
|
339
|
+
end
|
340
|
+
|
341
|
+
#
|
342
|
+
# Packages the routing info into a Rack application, suitable for
|
343
|
+
# insertion into a Rack app chain.
|
344
|
+
#
|
345
|
+
# Returns an instance of Rufus::Sixjo::App
|
346
|
+
#
|
347
|
+
def new_sixjo_rack_app (next_app, options={})
|
348
|
+
|
349
|
+
App.new(next_app, @routes, @helpers, @configures, options)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
data/test/ft_0_simple.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-sixjo
|
4
|
+
#
|
5
|
+
# jmettraux at gmail.org
|
6
|
+
#
|
7
|
+
# Fri Aug 8 15:14:45 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'testmixins'
|
12
|
+
|
13
|
+
#
|
14
|
+
# the "test" app
|
15
|
+
#
|
16
|
+
module Simple
|
17
|
+
extend Rufus::Sixjo
|
18
|
+
|
19
|
+
get '/toto' do
|
20
|
+
"toto"
|
21
|
+
end
|
22
|
+
|
23
|
+
get '/toto/:id' do
|
24
|
+
"toto with id #{params[:id]} .#{request.env['_FORMAT']}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class SimpleTest < Test::Unit::TestCase
|
29
|
+
include SixjoTestMixin
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@app = Simple.new_sixjo_rack_app(nil, :environment => 'test')
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_0
|
36
|
+
|
37
|
+
assert_equal 404, get('/nada').status
|
38
|
+
|
39
|
+
assert_equal 200, get('/toto').status
|
40
|
+
assert_equal "toto", @response.body
|
41
|
+
|
42
|
+
assert_equal 200, get('/toto/3').status
|
43
|
+
assert_equal "toto with id 3 .", @response.body
|
44
|
+
|
45
|
+
assert_equal 200, get('/toto/3.json').status
|
46
|
+
assert_equal "toto with id 3 .json", @response.body
|
47
|
+
|
48
|
+
assert_equal 200, get('/toto/3.json?q=nada').status
|
49
|
+
assert_equal "toto with id 3 .json", @response.body
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-sixjo
|
4
|
+
#
|
5
|
+
# jmettraux at gmail.org
|
6
|
+
#
|
7
|
+
# Sat Aug 9 00:03:47 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'testmixins'
|
12
|
+
|
13
|
+
#
|
14
|
+
# the "test" app
|
15
|
+
#
|
16
|
+
module WithHelper
|
17
|
+
extend Rufus::Sixjo
|
18
|
+
|
19
|
+
get '/hello' do
|
20
|
+
"hello #{hello}"
|
21
|
+
end
|
22
|
+
|
23
|
+
helpers do
|
24
|
+
def hello
|
25
|
+
params[:target]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class HelpersTest < Test::Unit::TestCase
|
31
|
+
include SixjoTestMixin
|
32
|
+
|
33
|
+
def setup
|
34
|
+
@app = WithHelper.new_sixjo_rack_app(nil, :environment => 'test')
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_0
|
38
|
+
|
39
|
+
assert_equal 200, get('/hello').status
|
40
|
+
assert_equal "hello ", @response.body
|
41
|
+
|
42
|
+
assert_equal 200, get('/hello?target=world').status
|
43
|
+
assert_equal "hello world", @response.body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-sixjo
|
4
|
+
#
|
5
|
+
# jmettraux at gmail.org
|
6
|
+
#
|
7
|
+
# Mon Aug 11 17:23:23 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'testmixins'
|
12
|
+
|
13
|
+
#
|
14
|
+
# the "test" app
|
15
|
+
#
|
16
|
+
module RedirectApp
|
17
|
+
extend Rufus::Sixjo
|
18
|
+
|
19
|
+
get '/' do
|
20
|
+
redirect '/elsewhere'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class RedirectTest < Test::Unit::TestCase
|
25
|
+
include SixjoTestMixin
|
26
|
+
|
27
|
+
def setup
|
28
|
+
@app = RedirectApp.new_sixjo_rack_app(nil, :environment => 'test')
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_0
|
32
|
+
assert_equal 303, get('/').status
|
33
|
+
assert_equal '/elsewhere', @response.location
|
34
|
+
assert_equal "303 redirecting to /elsewhere", @response.body
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/test/ft_3_erb.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-sixjo
|
4
|
+
#
|
5
|
+
# jmettraux at gmail.org
|
6
|
+
#
|
7
|
+
# Mon Aug 11 19:09:58 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'fileutils'
|
12
|
+
require 'testmixins'
|
13
|
+
|
14
|
+
#
|
15
|
+
# the "test" app
|
16
|
+
#
|
17
|
+
module ErbApp
|
18
|
+
extend Rufus::Sixjo
|
19
|
+
|
20
|
+
get '/' do
|
21
|
+
erb 'view0'
|
22
|
+
end
|
23
|
+
|
24
|
+
get '/good' do
|
25
|
+
erb 'view0', :locals => { :life => 'good' }
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/good2' do
|
29
|
+
erb :view0, :whatever => true, :locals => { :life => 'good' }
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/reckless' do
|
33
|
+
erb :view1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class ErbTest < Test::Unit::TestCase
|
38
|
+
include SixjoTestMixin
|
39
|
+
|
40
|
+
def setup
|
41
|
+
|
42
|
+
@app = ErbApp.new_sixjo_rack_app(nil, :environment => 'test')
|
43
|
+
|
44
|
+
FileUtils.mkdir('views') unless File.exist?('views')
|
45
|
+
|
46
|
+
fn = 'views/view0.erb'
|
47
|
+
|
48
|
+
FileUtils.rm(fn) if File.exist?(fn)
|
49
|
+
File.open(fn, 'w') { |f| f.write "this is view0, life is <%= life %>" }
|
50
|
+
|
51
|
+
fn = 'views/view1.erb'
|
52
|
+
|
53
|
+
FileUtils.rm(fn) if File.exist?(fn)
|
54
|
+
File.open(fn, 'w') { |f| f.write "<%= request.path_info %>" }
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_0
|
58
|
+
|
59
|
+
assert_equal 500, get('/').status
|
60
|
+
|
61
|
+
assert_equal 200, get('/good').status
|
62
|
+
assert_equal 'this is view0, life is good', @response.body.strip
|
63
|
+
|
64
|
+
assert_equal 200, get('/good2').status
|
65
|
+
assert_equal 'this is view0, life is good', @response.body.strip
|
66
|
+
|
67
|
+
assert_equal 200, get('/reckless').status
|
68
|
+
assert_equal '/reckless', @response.body.strip
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-sixjo
|
4
|
+
#
|
5
|
+
# jmettraux at gmail.org
|
6
|
+
#
|
7
|
+
# Tue Aug 12 13:38:16 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'testmixins'
|
12
|
+
|
13
|
+
#
|
14
|
+
# the "test" app
|
15
|
+
#
|
16
|
+
module ConfigureApp
|
17
|
+
extend Rufus::Sixjo
|
18
|
+
|
19
|
+
configure do
|
20
|
+
$apple = 'pomme'
|
21
|
+
@pear = 'poire'
|
22
|
+
end
|
23
|
+
|
24
|
+
configure :production, :development do
|
25
|
+
$peach = 'pe^che'
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/' do
|
29
|
+
"apple is #{$apple}"
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/pear' do
|
33
|
+
"pear is #{application.instance_variable_get(:@pear)}"
|
34
|
+
end
|
35
|
+
|
36
|
+
get '/peach' do
|
37
|
+
"peach is #{$peach}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class ConfigureTest < Test::Unit::TestCase
|
42
|
+
include SixjoTestMixin
|
43
|
+
|
44
|
+
def setup
|
45
|
+
|
46
|
+
@app = ConfigureApp.new_sixjo_rack_app(nil, :environment => 'test')
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_0
|
50
|
+
|
51
|
+
assert_equal 200, get('/').status
|
52
|
+
assert_equal 'apple is pomme', @response.body.strip
|
53
|
+
|
54
|
+
assert_equal 200, get('/pear').status
|
55
|
+
assert_equal 'pear is poire', @response.body.strip
|
56
|
+
|
57
|
+
assert_equal 200, get('/peach').status
|
58
|
+
assert_equal 'peach is', @response.body.strip
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
data/test/ft_5_put.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-sixjo
|
4
|
+
#
|
5
|
+
# jmettraux at gmail.org
|
6
|
+
#
|
7
|
+
# Tue Aug 12 23:36:22 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'testmixins'
|
12
|
+
|
13
|
+
#
|
14
|
+
# the "test" app
|
15
|
+
#
|
16
|
+
module PutApp
|
17
|
+
extend Rufus::Sixjo
|
18
|
+
|
19
|
+
post '/' do
|
20
|
+
#puts request.inspect
|
21
|
+
#request.env['rack.input'].read
|
22
|
+
request.content
|
23
|
+
end
|
24
|
+
|
25
|
+
put '/car' do
|
26
|
+
"put : #{request.content || params[:brand]}"
|
27
|
+
end
|
28
|
+
|
29
|
+
delete '/car/:id' do
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class PutTest < Test::Unit::TestCase
|
34
|
+
include SixjoTestMixin
|
35
|
+
|
36
|
+
def setup
|
37
|
+
|
38
|
+
@app = PutApp.new_sixjo_rack_app(nil, :environment => 'test')
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_0
|
42
|
+
|
43
|
+
#puts post('/', { :input => 'toto' }).body
|
44
|
+
assert_equal 200, post('/', { :input => 'toto' }).status
|
45
|
+
assert_equal 'toto', @response.body
|
46
|
+
|
47
|
+
assert_equal 200, put('/car', { :input => 'datsun' }).status
|
48
|
+
assert_equal 'put : datsun', @response.body
|
49
|
+
|
50
|
+
assert_equal 200, post('/car?_method=put', { :input => 'nissan' }).status
|
51
|
+
assert_equal 'put : nissan', @response.body
|
52
|
+
|
53
|
+
assert_equal 404, post('/car', { :input => 'mercedes', :_method => 'put' }).status
|
54
|
+
#assert_equal 'put : mercedes', @response.body
|
55
|
+
|
56
|
+
assert_equal 200, delete('/car/fr154147', {}).status
|
57
|
+
assert_equal '', @response.body
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_1
|
61
|
+
|
62
|
+
assert_equal(
|
63
|
+
200,
|
64
|
+
post(
|
65
|
+
'/car',
|
66
|
+
{ :input => 'lada', 'X-HTTP-Method-Override' => 'put' }).status)
|
67
|
+
assert_equal 'put : lada', @response.body
|
68
|
+
|
69
|
+
assert_equal(
|
70
|
+
400,
|
71
|
+
post(
|
72
|
+
'/car',
|
73
|
+
{ :input => 'lada', 'X-HTTP-Method-Override' => 'push' }).status)
|
74
|
+
assert_equal "unknown HTTP method 'PUSH'", @response.body
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_2
|
78
|
+
|
79
|
+
data = {
|
80
|
+
"_method" => "put",
|
81
|
+
"brand" => "ford"
|
82
|
+
}
|
83
|
+
form_data = encode_multipart(data)
|
84
|
+
|
85
|
+
assert_equal(
|
86
|
+
200,
|
87
|
+
post(
|
88
|
+
'/car',
|
89
|
+
{
|
90
|
+
:input => form_data,
|
91
|
+
'CONTENT_LENGTH' => form_data.length.to_s,
|
92
|
+
'CONTENT_TYPE' => 'multipart/form-data; boundary=AaB03x'
|
93
|
+
}).status)
|
94
|
+
assert_equal 'put : ford', @response.body
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
data/test/test.rb
ADDED
data/test/testmixins.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Testing rufus-sixjo
|
4
|
+
#
|
5
|
+
# jmettraux at gmail.org
|
6
|
+
#
|
7
|
+
# Fri Aug 8 18:01:29 JST 2008
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'rufus/sixjo'
|
12
|
+
|
13
|
+
|
14
|
+
module SixjoTestMixin
|
15
|
+
|
16
|
+
[ :post, :get, :put, :delete ].each do |v|
|
17
|
+
module_eval <<-EOS
|
18
|
+
def #{v} (path, options={})
|
19
|
+
@response = \
|
20
|
+
Rack::MockRequest.new(@app).request('#{v}'.upcase, path, options)
|
21
|
+
@response
|
22
|
+
end
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
|
26
|
+
MFD_BOUNDARY = "AaB03x"
|
27
|
+
|
28
|
+
def encode_multipart (data = {})
|
29
|
+
ret = ""
|
30
|
+
data.each do |key, value|
|
31
|
+
next if value == nil or value.strip == ''
|
32
|
+
ret << "--#{MFD_BOUNDARY}\r\n"
|
33
|
+
ret << "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n"
|
34
|
+
ret << value
|
35
|
+
ret << "\r\n"
|
36
|
+
end
|
37
|
+
ret << "--#{MFD_BOUNDARY}--\r\n"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rufus-sixjo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Mettraux
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-15 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: john at gmail dot com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.txt
|
33
|
+
files:
|
34
|
+
- lib/rufus
|
35
|
+
- lib/rufus/sixjo.rb
|
36
|
+
- test/ft_0_simple.rb
|
37
|
+
- test/ft_1_helpers.rb
|
38
|
+
- test/ft_2_redirect.rb
|
39
|
+
- test/ft_3_erb.rb
|
40
|
+
- test/ft_4_configure.rb
|
41
|
+
- test/ft_5_put.rb
|
42
|
+
- test/test.rb
|
43
|
+
- test/testmixins.rb
|
44
|
+
- README.txt
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://rufus.rubyforge.org/rufus-sixjo
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements:
|
65
|
+
- rack
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.2.0
|
68
|
+
signing_key:
|
69
|
+
specification_version: 2
|
70
|
+
summary: a rack application
|
71
|
+
test_files:
|
72
|
+
- test/test.rb
|