sinatra 1.2.3 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sinatra might be problematic. Click here for more details.
- data/CHANGES +33 -0
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.de.rdoc +11 -7
- data/README.es.rdoc +14 -7
- data/README.fr.rdoc +3 -3
- data/README.hu.rdoc +1 -1
- data/README.jp.rdoc +1 -1
- data/README.pt-br.rdoc +1 -1
- data/README.pt-pt.rdoc +1 -1
- data/README.rdoc +8 -6
- data/README.zh.rdoc +3 -3
- data/lib/sinatra/base.rb +40 -31
- data/sinatra.gemspec +3 -2
- data/test/delegator_test.rb +153 -0
- data/test/routing_test.rb +35 -4
- data/test/settings_test.rb +18 -0
- metadata +6 -6
data/CHANGES
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
= 1.2.6 / 2011-05-01
|
2
|
+
|
3
|
+
* Fix broken delegation, backport delegation tests from Sinatra 1.3.
|
4
|
+
(Konstantin Haase)
|
5
|
+
|
6
|
+
= 1.2.5 / 2011-04-30
|
7
|
+
|
8
|
+
* Restore compatibility with Ruby 1.8.6. (Konstantin Haase)
|
9
|
+
|
10
|
+
= 1.2.4 / 2011-04-30
|
11
|
+
|
12
|
+
* Sinatra::Application (classic style) does not use a session secret in
|
13
|
+
development mode, so sessions are not invalidated after every request when
|
14
|
+
using Shotgun. (Konstantin Haase)
|
15
|
+
|
16
|
+
* The request object was shared between multiple Sinatra instances in the
|
17
|
+
same middleware chain. This caused issues if any non-sinatra routing
|
18
|
+
happend in-between two of those instances, or running a request twice
|
19
|
+
against an application (described in the README). The caching was reverted.
|
20
|
+
See GH#239 and GH#256 for more infos. (Konstantin Haase)
|
21
|
+
|
22
|
+
* Fixes issues where the top level DSL was interfering with method_missing
|
23
|
+
proxies. This issue surfaced when Rails 3 was used with older Sass versions
|
24
|
+
and Sinatra >= 1.2.0. (Konstantin Haase)
|
25
|
+
|
26
|
+
* Sinatra::Delegator.delegate is now able to delegate any method names, even
|
27
|
+
those containing special characters. This allows better integration into
|
28
|
+
other programming languages on Rubinius (probably on the JVM, too), like
|
29
|
+
Fancy. (Konstantin Haase)
|
30
|
+
|
31
|
+
* Remove HEAD request logic and let Rack::Head handle it instead. (Paolo
|
32
|
+
"Nusco" Perrotta)
|
33
|
+
|
1
34
|
= 1.2.3 / 2011-04-13
|
2
35
|
|
3
36
|
* This release is compatible with Tilt 1.3, it will still work with Tilt 1.2.2,
|
data/Gemfile
CHANGED
@@ -17,7 +17,7 @@ gem 'rack-test', '>= 0.5.6'
|
|
17
17
|
|
18
18
|
# Allows stuff like `tilt=1.2.2 bundle install` or `tilt=master ...`.
|
19
19
|
# Used by the CI.
|
20
|
-
tilt = ENV['tilt']
|
20
|
+
tilt = (ENV['tilt'] || 'stable').dup
|
21
21
|
tilt.sub! 'tilt-', ''
|
22
22
|
if tilt != 'stable'
|
23
23
|
tilt = {:git => TILT_REPO, :branch => tilt} unless tilt =~ /(\d+\.)+\d+/
|
data/LICENSE
CHANGED
data/README.de.rdoc
CHANGED
@@ -903,8 +903,8 @@ Manchmal entspricht +pass+ nicht den Anforderungen, wenn das Ergebnis einer
|
|
903
903
|
anderen Route gefordert wird. Um das zu erreichen, lässt sich +call+ nutzen:
|
904
904
|
|
905
905
|
get '/foo' do
|
906
|
-
status, headers, body = call
|
907
|
-
[status, body.upcase]
|
906
|
+
status, headers, body = call env.merge("PATH_INFO" => '/bar')
|
907
|
+
[status, headers, body.map(&:upcase)]
|
908
908
|
end
|
909
909
|
|
910
910
|
get '/bar' do
|
@@ -1357,7 +1357,7 @@ Routen-Block oder in einem Filter geworfen wurde. Die Exception kann über die
|
|
1357
1357
|
Benutzerdefinierte Fehler:
|
1358
1358
|
|
1359
1359
|
error MeinFehler do
|
1360
|
-
'Au weia, ' +
|
1360
|
+
'Au weia, ' + env['sinatra.error'].message
|
1361
1361
|
end
|
1362
1362
|
|
1363
1363
|
Dann, wenn das passiert:
|
@@ -1819,10 +1819,10 @@ die so installiert werden:
|
|
1819
1819
|
=== Mit Bundler
|
1820
1820
|
|
1821
1821
|
Wenn die Applikation mit der neuesten Version von Sinatra und
|
1822
|
-
{Bundler}[http://gembundler.com/] genutzt werden soll,
|
1823
|
-
Weg
|
1822
|
+
{Bundler}[http://gembundler.com/] genutzt werden soll, empfehlen wir den
|
1823
|
+
nachfolgenden Weg.
|
1824
1824
|
|
1825
|
-
Soweit Bundler noch nicht installiert ist
|
1825
|
+
Soweit Bundler noch nicht installiert ist:
|
1826
1826
|
|
1827
1827
|
gem install bundler
|
1828
1828
|
|
@@ -1897,9 +1897,13 @@ SemVer und SemVerTag.
|
|
1897
1897
|
* {Projekt-Website}[http://sinatra.github.com/] - Ergänzende Dokumentation,
|
1898
1898
|
News und Links zu anderen Ressourcen.
|
1899
1899
|
* {Hilfe beisteuern}[http://sinatra.github.com/contributing.html] - Einen
|
1900
|
-
Fehler gefunden? Brauchst du Hilfe? Hast du einen Patch?
|
1900
|
+
Fehler gefunden? Brauchst du Hilfe? Hast du einen Patch?
|
1901
1901
|
* {Issue-Tracker}[http://github.com/sinatra/sinatra/issues]
|
1902
1902
|
* {Twitter}[http://twitter.com/sinatra]
|
1903
1903
|
* {Mailing-Liste}[http://groups.google.com/group/sinatrarb]
|
1904
1904
|
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] auf http://freenode.net
|
1905
1905
|
|
1906
|
+
* API Dokumentation für die {aktuelle Version}[http://rubydoc.info/gems/sinatra]
|
1907
|
+
oder für {HEAD}[http://rubydoc.info/github/sinatra/sinatra] auf
|
1908
|
+
http://rubydoc.info
|
1909
|
+
|
data/README.es.rdoc
CHANGED
@@ -874,8 +874,8 @@ Cuando querés obtener el resultado de la llamada a una ruta, +pass+ no te va a
|
|
874
874
|
servir. Para lograr esto, podés usar +call+:
|
875
875
|
|
876
876
|
get '/foo' do
|
877
|
-
status, headers, body = call
|
878
|
-
[status, body.upcase]
|
877
|
+
status, headers, body = call env.merge("PATH_INFO" => '/bar')
|
878
|
+
[status, headers, body.map(&:upcase)]
|
879
879
|
end
|
880
880
|
|
881
881
|
get '/bar' do
|
@@ -1331,9 +1331,11 @@ Podés acceder a estas opciones utilizando el método <tt>settings</tt>:
|
|
1331
1331
|
[static] define si Sinatra debe encargarse de servir archivos
|
1332
1332
|
estáticos.
|
1333
1333
|
|
1334
|
-
Deshabilitala cuando usés un servidor capaz de
|
1335
|
-
por sí solo, porque mejorará el
|
1336
|
-
habilitada por
|
1334
|
+
Deshabilitala cuando usés un servidor capaz de
|
1335
|
+
hacerlo por sí solo, porque mejorará el
|
1336
|
+
rendimiento. Se encuentra habilitada por
|
1337
|
+
defecto en el estilo clásico y desactivado en el
|
1338
|
+
el modular.
|
1337
1339
|
|
1338
1340
|
[views] directorio de las vistas.
|
1339
1341
|
|
@@ -1365,7 +1367,7 @@ obtener de la variable Rack <tt>sinatra.error</tt>:
|
|
1365
1367
|
Errores personalizados:
|
1366
1368
|
|
1367
1369
|
error MiErrorPersonalizado do
|
1368
|
-
'Lo que pasó fue...'
|
1370
|
+
'Lo que pasó fue...' + env['sinatra.error'].message
|
1369
1371
|
end
|
1370
1372
|
|
1371
1373
|
Entonces, si pasa esto:
|
@@ -1534,6 +1536,7 @@ entre sus configuraciones:
|
|
1534
1536
|
logging true false
|
1535
1537
|
method_override true false
|
1536
1538
|
inline_templates true false
|
1539
|
+
static true false
|
1537
1540
|
|
1538
1541
|
=== Sirviendo una Aplicación Modular
|
1539
1542
|
|
@@ -1633,7 +1636,7 @@ aplicación basada en Rack (Rails/Ramaze/Camping/...):
|
|
1633
1636
|
|
1634
1637
|
Puede que en algunas ocasiones quieras crear nuevas aplicaciones en
|
1635
1638
|
tiempo de ejecución sin tener que asignarlas a una constante. Para
|
1636
|
-
esto tenés
|
1639
|
+
esto tenés <tt>Sinatra.new</tt>:
|
1637
1640
|
|
1638
1641
|
require 'sinatra/base'
|
1639
1642
|
mi_app = Sinatra.new { get('/') { "hola" } }
|
@@ -1909,3 +1912,7 @@ siguiendo las especificaciones SemVer y SemVerTag.
|
|
1909
1912
|
* {Twitter}[http://twitter.com/sinatra]
|
1910
1913
|
* {Lista de Correo}[http://groups.google.com/group/sinatrarb/topics]
|
1911
1914
|
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] en http://freenode.net
|
1915
|
+
* Documentación de la API para la
|
1916
|
+
{última versión liberada}[http://rubydoc.info/gems/sinatra] o para la
|
1917
|
+
{rama de desarrollo actual}[http://rubydoc.info/github/sinatra/sinatra]
|
1918
|
+
en http://rubydoc.info/
|
data/README.fr.rdoc
CHANGED
@@ -894,8 +894,8 @@ souhaitez obtenir le résultat d'une autre route. Pour cela, utilisez
|
|
894
894
|
simplement +call+ :
|
895
895
|
|
896
896
|
get '/foo' do
|
897
|
-
status, headers, body = call
|
898
|
-
[status, body.upcase]
|
897
|
+
status, headers, body = call env.merge("PATH_INFO" => '/bar')
|
898
|
+
[status, headers, body.map(&:upcase)]
|
899
899
|
end
|
900
900
|
|
901
901
|
get '/bar' do
|
@@ -1399,7 +1399,7 @@ variable Rack <tt>sinatra.error</tt>:
|
|
1399
1399
|
Erreur sur mesure:
|
1400
1400
|
|
1401
1401
|
error MonErreurSurMesure do
|
1402
|
-
'Donc il est arrivé ceci...' +
|
1402
|
+
'Donc il est arrivé ceci...' + env['sinatra.error'].message
|
1403
1403
|
end
|
1404
1404
|
|
1405
1405
|
Donc si ceci arrive:
|
data/README.hu.rdoc
CHANGED
@@ -399,7 +399,7 @@ előszűrő kivételt vált ki. A kivétel objektum lehívható a
|
|
399
399
|
Egyéni hibakezelés:
|
400
400
|
|
401
401
|
error MyCustomError do
|
402
|
-
'Szóval az van, hogy...' +
|
402
|
+
'Szóval az van, hogy...' + env['sinatra.error'].message
|
403
403
|
end
|
404
404
|
|
405
405
|
És amikor fellép:
|
data/README.jp.rdoc
CHANGED
data/README.pt-br.rdoc
CHANGED
@@ -431,7 +431,7 @@ Rack <tt>sinatra.error</tt>:
|
|
431
431
|
Erros customizados:
|
432
432
|
|
433
433
|
error MeuErroCustomizado do
|
434
|
-
'Então que aconteceu foi...' +
|
434
|
+
'Então que aconteceu foi...' + env['sinatra.error'].message
|
435
435
|
end
|
436
436
|
|
437
437
|
Então, se isso acontecer:
|
data/README.pt-pt.rdoc
CHANGED
@@ -430,7 +430,7 @@ Rack <tt>sinatra.error</tt>:
|
|
430
430
|
Erros personalizados:
|
431
431
|
|
432
432
|
error MeuErroPersonalizado do
|
433
|
-
'O que aconteceu foi...' +
|
433
|
+
'O que aconteceu foi...' + env['sinatra.error'].message
|
434
434
|
end
|
435
435
|
|
436
436
|
Então, se isso acontecer:
|
data/README.rdoc
CHANGED
@@ -854,8 +854,8 @@ Sometimes +pass+ is not what you want, instead you would like to get the result
|
|
854
854
|
of calling another route. Simply use +call+ to achieve this:
|
855
855
|
|
856
856
|
get '/foo' do
|
857
|
-
status, headers, body = call
|
858
|
-
[status, body.upcase]
|
857
|
+
status, headers, body = call env.merge("PATH_INFO" => '/bar')
|
858
|
+
[status, headers, body.map(&:upcase)]
|
859
859
|
end
|
860
860
|
|
861
861
|
get '/bar' do
|
@@ -1325,7 +1325,7 @@ block or a filter. The exception object can be obtained from the
|
|
1325
1325
|
Custom errors:
|
1326
1326
|
|
1327
1327
|
error MyCustomError do
|
1328
|
-
'So what happened was...' +
|
1328
|
+
'So what happened was...' + env['sinatra.error'].message
|
1329
1329
|
end
|
1330
1330
|
|
1331
1331
|
Then, if this happens:
|
@@ -1478,8 +1478,8 @@ There are only two downsides compared with modular style:
|
|
1478
1478
|
|
1479
1479
|
There is no reason you cannot mix modular and classic style.
|
1480
1480
|
|
1481
|
-
If switching from one style to the other, you should be aware of
|
1482
|
-
|
1481
|
+
If switching from one style to the other, you should be aware of slightly
|
1482
|
+
different default settings:
|
1483
1483
|
|
1484
1484
|
Setting Classic Modular
|
1485
1485
|
|
@@ -1587,7 +1587,7 @@ application (Rails/Ramaze/Camping/...):
|
|
1587
1587
|
=== Dynamic Application Creation
|
1588
1588
|
|
1589
1589
|
Sometimes you want to create new applications at runtime without having to
|
1590
|
-
assign them to a constant, you can do this with
|
1590
|
+
assign them to a constant, you can do this with <tt>Sinatra.new</tt>:
|
1591
1591
|
|
1592
1592
|
require 'sinatra/base'
|
1593
1593
|
my_app = Sinatra.new { get('/') { "hi" } }
|
@@ -1855,6 +1855,8 @@ SemVerTag.
|
|
1855
1855
|
* {Twitter}[http://twitter.com/sinatra]
|
1856
1856
|
* {Mailing List}[http://groups.google.com/group/sinatrarb/topics]
|
1857
1857
|
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net
|
1858
|
+
* {Sinatra Book}[http://sinatra-book.gittr.com] Cookbook Tutorial
|
1859
|
+
* {Sinatra Book Contrib}[http://sinatra-book-contrib.com/] Community contributed recipes
|
1858
1860
|
* API documentation for the {latest release}[http://rubydoc.info/gems/sinatra]
|
1859
1861
|
or the {current HEAD}[http://rubydoc.info/github/sinatra/sinatra] on
|
1860
1862
|
http://rubydoc.info/
|
data/README.zh.rdoc
CHANGED
@@ -843,8 +843,8 @@ Session被用来在请求之间保持状态。如果被激活,每一个用户
|
|
843
843
|
。简单的使用 +call+ 可以做到这一点:
|
844
844
|
|
845
845
|
get '/foo' do
|
846
|
-
status, headers, body = call
|
847
|
-
[status, body.upcase]
|
846
|
+
status, headers, body = call env.merge("PATH_INFO" => '/bar')
|
847
|
+
[status, headers, body.map(&:upcase)]
|
848
848
|
end
|
849
849
|
|
850
850
|
get '/bar' do
|
@@ -1314,7 +1314,7 @@ Sinatra会自动处理range请求。
|
|
1314
1314
|
自定义错误:
|
1315
1315
|
|
1316
1316
|
error MyCustomError do
|
1317
|
-
'So what happened was...' +
|
1317
|
+
'So what happened was...' + env['sinatra.error'].message
|
1318
1318
|
end
|
1319
1319
|
|
1320
1320
|
那么,当这个发生的时候:
|
data/lib/sinatra/base.rb
CHANGED
@@ -7,15 +7,11 @@ require 'sinatra/showexceptions'
|
|
7
7
|
require 'tilt'
|
8
8
|
|
9
9
|
module Sinatra
|
10
|
-
VERSION = '1.2.
|
10
|
+
VERSION = '1.2.6'
|
11
11
|
|
12
12
|
# The request object. See Rack::Request for more info:
|
13
13
|
# http://rack.rubyforge.org/doc/classes/Rack/Request.html
|
14
14
|
class Request < Rack::Request
|
15
|
-
def self.new(env)
|
16
|
-
env['sinatra.request'] ||= super
|
17
|
-
end
|
18
|
-
|
19
15
|
# Returns an array of acceptable media types for the response
|
20
16
|
def accept
|
21
17
|
@env['sinatra.accept'] ||= begin
|
@@ -63,7 +59,7 @@ module Sinatra
|
|
63
59
|
def accept_entry(entry)
|
64
60
|
type, *options = entry.gsub(/\s/, '').split(';')
|
65
61
|
quality = 0 # we sort smalles first
|
66
|
-
options.delete_if { |e| quality = 1 - e[2..-1].to_f if e
|
62
|
+
options.delete_if { |e| quality = 1 - e[2..-1].to_f if e =~ /^q=/ }
|
67
63
|
[type, [quality, type.count('*'), 1 - options.size]]
|
68
64
|
end
|
69
65
|
end
|
@@ -371,7 +367,7 @@ module Sinatra
|
|
371
367
|
time = time_for time
|
372
368
|
response['Last-Modified'] = time.httpdate
|
373
369
|
# compare based on seconds since epoch
|
374
|
-
halt 304 if Time.httpdate(
|
370
|
+
halt 304 if Time.httpdate(env['HTTP_IF_MODIFIED_SINCE']).to_i >= time.to_i
|
375
371
|
rescue ArgumentError
|
376
372
|
end
|
377
373
|
|
@@ -655,17 +651,7 @@ module Sinatra
|
|
655
651
|
end
|
656
652
|
end
|
657
653
|
|
658
|
-
|
659
|
-
|
660
|
-
# Never produce a body on HEAD requests. Do retain the Content-Length
|
661
|
-
# unless it's "0", in which case we assume it was calculated erroneously
|
662
|
-
# for a manual HEAD response and remove it entirely.
|
663
|
-
if @env['REQUEST_METHOD'] == 'HEAD'
|
664
|
-
body = []
|
665
|
-
header.delete('Content-Length') if header['Content-Length'] == '0'
|
666
|
-
end
|
667
|
-
|
668
|
-
[status, header, body]
|
654
|
+
@response.finish
|
669
655
|
end
|
670
656
|
|
671
657
|
# Access settings defined with Base.set.
|
@@ -700,7 +686,7 @@ module Sinatra
|
|
700
686
|
# Forward the request to the downstream app -- middleware only.
|
701
687
|
def forward
|
702
688
|
fail "downstream app not set" unless @app.respond_to? :call
|
703
|
-
status, headers, body = @app.call
|
689
|
+
status, headers, body = @app.call env
|
704
690
|
@response.status = status
|
705
691
|
@response.body = body
|
706
692
|
@response.headers.merge! headers
|
@@ -953,14 +939,15 @@ module Sinatra
|
|
953
939
|
|
954
940
|
# Sets an option to the given value. If the value is a proc,
|
955
941
|
# the proc will be called every time the option is accessed.
|
956
|
-
def set(option, value=
|
957
|
-
raise ArgumentError if block
|
942
|
+
def set(option, value = (not_set = true), &block)
|
943
|
+
raise ArgumentError if block and !not_set
|
958
944
|
value = block if block
|
959
945
|
if value.kind_of?(Proc)
|
960
946
|
metadef(option, &value)
|
961
947
|
metadef("#{option}?") { !!__send__(option) }
|
962
948
|
metadef("#{option}=") { |val| metadef(option, &Proc.new{val}) }
|
963
|
-
elsif
|
949
|
+
elsif not_set
|
950
|
+
raise ArgumentError unless option.respond_to?(:each)
|
964
951
|
option.each { |k,v| set(k, v) }
|
965
952
|
elsif respond_to?("#{option}=")
|
966
953
|
__send__ "#{option}=", value
|
@@ -1274,6 +1261,7 @@ module Sinatra
|
|
1274
1261
|
builder.use Rack::MethodOverride if method_override?
|
1275
1262
|
builder.use ShowExceptions if show_exceptions?
|
1276
1263
|
builder.use Rack::CommonLogger if logging?
|
1264
|
+
builder.use Rack::Head
|
1277
1265
|
setup_sessions builder
|
1278
1266
|
middleware.each { |c,a,b| builder.use(c, *a, &b) }
|
1279
1267
|
builder.run new!(*args, &bk)
|
@@ -1440,7 +1428,7 @@ module Sinatra
|
|
1440
1428
|
</style>
|
1441
1429
|
</head>
|
1442
1430
|
<body>
|
1443
|
-
<h2>Sinatra doesn
|
1431
|
+
<h2>Sinatra doesn’t know this ditty.</h2>
|
1444
1432
|
<img src='#{uri "/__sinatra__/404.png"}'>
|
1445
1433
|
<div id="c">
|
1446
1434
|
Try this:
|
@@ -1464,6 +1452,7 @@ module Sinatra
|
|
1464
1452
|
set :logging, Proc.new { ! test? }
|
1465
1453
|
set :method_override, true
|
1466
1454
|
set :run, Proc.new { ! test? }
|
1455
|
+
set :session_secret, Proc.new { super() unless development? }
|
1467
1456
|
|
1468
1457
|
def self.register(*extensions, &block) #:nodoc:
|
1469
1458
|
added_methods = extensions.map {|m| m.public_instance_methods }.flatten
|
@@ -1476,14 +1465,28 @@ module Sinatra
|
|
1476
1465
|
# methods to be delegated to the Sinatra::Application class. Used primarily
|
1477
1466
|
# at the top-level.
|
1478
1467
|
module Delegator #:nodoc:
|
1468
|
+
TEMPLATE = <<-RUBY
|
1469
|
+
def %1$s(*args, &b)
|
1470
|
+
return super if respond_to? :%1$s
|
1471
|
+
::Sinatra::Delegator.target.send("%2$s", *args, &b)
|
1472
|
+
end
|
1473
|
+
RUBY
|
1474
|
+
|
1479
1475
|
def self.delegate(*methods)
|
1480
1476
|
methods.each do |method_name|
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1477
|
+
# Replaced with way shorter and better implementation in 1.3.0
|
1478
|
+
# using define_method instead, however, blocks cannot take block
|
1479
|
+
# arguments on 1.8.6.
|
1480
|
+
begin
|
1481
|
+
code = TEMPLATE % [method_name, method_name]
|
1482
|
+
eval code, binding, '(__DELEGATE__)', 1
|
1483
|
+
rescue SyntaxError
|
1484
|
+
code = TEMPLATE % [:_delegate, method_name]
|
1485
|
+
eval code, binding, '(__DELEGATE__)', 1
|
1486
|
+
alias_method method_name, :_delegate
|
1487
|
+
undef_method :_delegate
|
1488
|
+
end
|
1489
|
+
private method_name
|
1487
1490
|
end
|
1488
1491
|
end
|
1489
1492
|
|
@@ -1491,6 +1494,12 @@ module Sinatra
|
|
1491
1494
|
:before, :after, :error, :not_found, :configure, :set, :mime_type,
|
1492
1495
|
:enable, :disable, :use, :development?, :test?, :production?,
|
1493
1496
|
:helpers, :settings
|
1497
|
+
|
1498
|
+
class << self
|
1499
|
+
attr_accessor :target
|
1500
|
+
end
|
1501
|
+
|
1502
|
+
self.target = Application
|
1494
1503
|
end
|
1495
1504
|
|
1496
1505
|
# Create a new Sinatra application. The block is evaluated in the new app's
|
@@ -1503,11 +1512,11 @@ module Sinatra
|
|
1503
1512
|
|
1504
1513
|
# Extend the top-level DSL with the modules provided.
|
1505
1514
|
def self.register(*extensions, &block)
|
1506
|
-
|
1515
|
+
Delegator.target.register(*extensions, &block)
|
1507
1516
|
end
|
1508
1517
|
|
1509
1518
|
# Include the helper modules provided in Sinatra's request context.
|
1510
1519
|
def self.helpers(*extensions, &block)
|
1511
|
-
|
1520
|
+
Delegator.target.helpers(*extensions, &block)
|
1512
1521
|
end
|
1513
1522
|
end
|
data/sinatra.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
4
|
|
5
5
|
s.name = 'sinatra'
|
6
|
-
s.version = '1.2.
|
7
|
-
s.date = '2011-
|
6
|
+
s.version = '1.2.6'
|
7
|
+
s.date = '2011-05-01'
|
8
8
|
|
9
9
|
s.description = "Classy web-development dressed in a DSL"
|
10
10
|
s.summary = "Classy web-development dressed in a DSL"
|
@@ -40,6 +40,7 @@ Gem::Specification.new do |s|
|
|
40
40
|
test/builder_test.rb
|
41
41
|
test/coffee_test.rb
|
42
42
|
test/contest.rb
|
43
|
+
test/delegator_test.rb
|
43
44
|
test/encoding_test.rb
|
44
45
|
test/erb_test.rb
|
45
46
|
test/erubis_test.rb
|
@@ -0,0 +1,153 @@
|
|
1
|
+
class DelegatorTest < Test::Unit::TestCase
|
2
|
+
class Mirror
|
3
|
+
attr_reader :last_call
|
4
|
+
def method_missing(*a, &b)
|
5
|
+
@last_call = [*a.map(&:to_s)]
|
6
|
+
@last_call << b if b
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.delegates(name)
|
11
|
+
it "delegates #{name}" do
|
12
|
+
m = mirror { send name }
|
13
|
+
assert_equal m.last_call, [name.to_s]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "delegates #{name} with arguments" do
|
17
|
+
m = mirror { send name, "foo", "bar" }
|
18
|
+
assert_equal m.last_call, [name.to_s, "foo", "bar"]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "delegates #{name} with block" do
|
22
|
+
block = proc { }
|
23
|
+
m = mirror { send(name, &block) }
|
24
|
+
assert_equal m.last_call, [name.to_s, block]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
setup do
|
29
|
+
@target_was = Sinatra::Delegator.target
|
30
|
+
end
|
31
|
+
|
32
|
+
def teardown
|
33
|
+
Sinatra::Delegator.target = @target_was
|
34
|
+
end
|
35
|
+
|
36
|
+
def delegation_app(&block)
|
37
|
+
mock_app { Sinatra::Delegator.target = self }
|
38
|
+
delegate(&block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def mirror(&block)
|
42
|
+
mirror = Mirror.new
|
43
|
+
Sinatra::Delegator.target = mirror
|
44
|
+
delegate(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def delegate(&block)
|
48
|
+
assert Sinatra::Delegator.target != Sinatra::Application
|
49
|
+
Object.new.extend(Sinatra::Delegator).instance_eval(&block) if block
|
50
|
+
Sinatra::Delegator.target
|
51
|
+
end
|
52
|
+
|
53
|
+
def target
|
54
|
+
Sinatra::Delegator.target
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'defaults to Sinatra::Application as target' do
|
58
|
+
assert_equal Sinatra::Delegator.target, Sinatra::Application
|
59
|
+
end
|
60
|
+
|
61
|
+
%w[get put post delete options].each do |verb|
|
62
|
+
it "delegates #{verb} correctly" do
|
63
|
+
delegation_app do
|
64
|
+
send verb, '/hello' do
|
65
|
+
'Hello World'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
request = Rack::MockRequest.new(@app)
|
70
|
+
response = request.request(verb.upcase, '/hello', {})
|
71
|
+
assert response.ok?
|
72
|
+
assert_equal 'Hello World', response.body
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "delegates head correctly" do
|
77
|
+
delegation_app do
|
78
|
+
head '/hello' do
|
79
|
+
response['X-Hello'] = 'World!'
|
80
|
+
'remove me'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
request = Rack::MockRequest.new(@app)
|
85
|
+
response = request.request('HEAD', '/hello', {})
|
86
|
+
assert response.ok?
|
87
|
+
assert_equal 'World!', response['X-Hello']
|
88
|
+
assert_equal '', response.body
|
89
|
+
end
|
90
|
+
|
91
|
+
it "registers extensions with the delegation target" do
|
92
|
+
app, mixin = mirror, Module.new
|
93
|
+
Sinatra.register mixin
|
94
|
+
assert_equal app.last_call, ["register", mixin.to_s ]
|
95
|
+
end
|
96
|
+
|
97
|
+
it "registers helpers with the delegation target" do
|
98
|
+
app, mixin = mirror, Module.new
|
99
|
+
Sinatra.helpers mixin
|
100
|
+
assert_equal app.last_call, ["helpers", mixin.to_s ]
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should work with method_missing proxies for options" do
|
104
|
+
mixin = Module.new do
|
105
|
+
def respond_to?(method, *)
|
106
|
+
method.to_sym == :options or super
|
107
|
+
end
|
108
|
+
|
109
|
+
def method_missing(method, *args, &block)
|
110
|
+
return super unless method.to_sym == :options
|
111
|
+
{:some => :option}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
value = nil
|
116
|
+
mirror do
|
117
|
+
extend mixin
|
118
|
+
value = options
|
119
|
+
end
|
120
|
+
|
121
|
+
assert_equal({:some => :option}, value)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "delegates crazy method names" do
|
125
|
+
Sinatra::Delegator.delegate "foo:bar:"
|
126
|
+
method = mirror { send "foo:bar:" }.last_call.first
|
127
|
+
assert_equal "foo:bar:", method
|
128
|
+
end
|
129
|
+
|
130
|
+
delegates 'get'
|
131
|
+
delegates 'put'
|
132
|
+
delegates 'post'
|
133
|
+
delegates 'delete'
|
134
|
+
delegates 'head'
|
135
|
+
delegates 'options'
|
136
|
+
delegates 'template'
|
137
|
+
delegates 'layout'
|
138
|
+
delegates 'before'
|
139
|
+
delegates 'after'
|
140
|
+
delegates 'error'
|
141
|
+
delegates 'not_found'
|
142
|
+
delegates 'configure'
|
143
|
+
delegates 'set'
|
144
|
+
delegates 'mime_type'
|
145
|
+
delegates 'enable'
|
146
|
+
delegates 'disable'
|
147
|
+
delegates 'use'
|
148
|
+
delegates 'development?'
|
149
|
+
delegates 'test?'
|
150
|
+
delegates 'production?'
|
151
|
+
delegates 'helpers'
|
152
|
+
delegates 'settings'
|
153
|
+
end
|
data/test/routing_test.rb
CHANGED
@@ -686,10 +686,10 @@ class RoutingTest < Test::Unit::TestCase
|
|
686
686
|
it "filters by accept header" do
|
687
687
|
mock_app {
|
688
688
|
get '/', :provides => :xml do
|
689
|
-
|
689
|
+
env['HTTP_ACCEPT']
|
690
690
|
end
|
691
691
|
get '/foo', :provides => :html do
|
692
|
-
|
692
|
+
env['HTTP_ACCEPT']
|
693
693
|
end
|
694
694
|
}
|
695
695
|
|
@@ -714,7 +714,7 @@ class RoutingTest < Test::Unit::TestCase
|
|
714
714
|
|
715
715
|
mock_app {
|
716
716
|
get '/', :provides => types do
|
717
|
-
|
717
|
+
env['HTTP_ACCEPT']
|
718
718
|
end
|
719
719
|
}
|
720
720
|
|
@@ -729,7 +729,7 @@ class RoutingTest < Test::Unit::TestCase
|
|
729
729
|
it 'degrades gracefully when optional accept header is not provided' do
|
730
730
|
mock_app {
|
731
731
|
get '/', :provides => :xml do
|
732
|
-
|
732
|
+
env['HTTP_ACCEPT']
|
733
733
|
end
|
734
734
|
get '/' do
|
735
735
|
'default'
|
@@ -1042,4 +1042,35 @@ class RoutingTest < Test::Unit::TestCase
|
|
1042
1042
|
get '/foo'
|
1043
1043
|
assert not_found?
|
1044
1044
|
end
|
1045
|
+
|
1046
|
+
it 'allows using call to fire another request internally' do
|
1047
|
+
mock_app do
|
1048
|
+
get '/foo' do
|
1049
|
+
status, headers, body = call env.merge("PATH_INFO" => '/bar')
|
1050
|
+
[status, headers, body.map(&:upcase)]
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
get '/bar' do
|
1054
|
+
"bar"
|
1055
|
+
end
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
get '/foo'
|
1059
|
+
assert ok?
|
1060
|
+
assert_body "BAR"
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
it 'plays well with other routing middleware' do
|
1064
|
+
middleware = Sinatra.new
|
1065
|
+
inner_app = Sinatra.new { get('/foo') { 'hello' } }
|
1066
|
+
builder = Rack::Builder.new do
|
1067
|
+
use middleware
|
1068
|
+
map('/test') { run inner_app }
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
@app = builder.to_app
|
1072
|
+
get '/test/foo'
|
1073
|
+
assert ok?
|
1074
|
+
assert_body 'hello'
|
1075
|
+
end
|
1045
1076
|
end
|
data/test/settings_test.rb
CHANGED
@@ -34,6 +34,24 @@ class SettingsTest < Test::Unit::TestCase
|
|
34
34
|
assert !@base.respond_to?(:fiz)
|
35
35
|
end
|
36
36
|
|
37
|
+
it 'raises an error without value and block' do
|
38
|
+
assert_raise(ArgumentError) { @base.set(:fiz) }
|
39
|
+
assert !@base.respond_to?(:fiz)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'allows setting a value to the app class' do
|
43
|
+
@base.set :base, @base
|
44
|
+
assert @base.respond_to?(:base)
|
45
|
+
assert_equal @base, @base.base
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'raises an error with the app class as value and a block' do
|
49
|
+
assert_raise ArgumentError do
|
50
|
+
@base.set(:fiz, @base) { 'baz' }
|
51
|
+
end
|
52
|
+
assert !@base.respond_to?(:fiz)
|
53
|
+
end
|
54
|
+
|
37
55
|
it "sets multiple settings with a Hash" do
|
38
56
|
@base.set :foo => 1234,
|
39
57
|
:bar => 'Hello World',
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: sinatra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.2.
|
5
|
+
version: 1.2.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Blake Mizerany
|
@@ -13,8 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2011-
|
17
|
-
default_executable:
|
16
|
+
date: 2011-05-01 00:00:00 Z
|
18
17
|
dependencies:
|
19
18
|
- !ruby/object:Gem::Dependency
|
20
19
|
name: rack
|
@@ -94,6 +93,7 @@ files:
|
|
94
93
|
- test/builder_test.rb
|
95
94
|
- test/coffee_test.rb
|
96
95
|
- test/contest.rb
|
96
|
+
- test/delegator_test.rb
|
97
97
|
- test/encoding_test.rb
|
98
98
|
- test/erb_test.rb
|
99
99
|
- test/erubis_test.rb
|
@@ -169,7 +169,6 @@ files:
|
|
169
169
|
- test/views/layout2.test
|
170
170
|
- test/views/nested.str
|
171
171
|
- test/views/utf8.erb
|
172
|
-
has_rdoc: true
|
173
172
|
homepage: http://sinatra.rubyforge.org
|
174
173
|
licenses: []
|
175
174
|
|
@@ -188,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
188
187
|
requirements:
|
189
188
|
- - ">="
|
190
189
|
- !ruby/object:Gem::Version
|
191
|
-
hash: -
|
190
|
+
hash: -2370709599790999687
|
192
191
|
segments:
|
193
192
|
- 0
|
194
193
|
version: "0"
|
@@ -201,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
200
|
requirements: []
|
202
201
|
|
203
202
|
rubyforge_project: sinatra
|
204
|
-
rubygems_version: 1.
|
203
|
+
rubygems_version: 1.7.2
|
205
204
|
signing_key:
|
206
205
|
specification_version: 2
|
207
206
|
summary: Classy web-development dressed in a DSL
|
@@ -209,6 +208,7 @@ test_files:
|
|
209
208
|
- test/base_test.rb
|
210
209
|
- test/builder_test.rb
|
211
210
|
- test/coffee_test.rb
|
211
|
+
- test/delegator_test.rb
|
212
212
|
- test/encoding_test.rb
|
213
213
|
- test/erb_test.rb
|
214
214
|
- test/erubis_test.rb
|