Merge branch 'master' of github.com:sinatra/sinatra
This commit is contained in:
commit
4d40a5e26c
|
@ -551,6 +551,15 @@ Las opciones <tt>:callback</tt> y <tt>:variable</tt> se pueden utilizar para dec
|
||||||
|
|
||||||
var resource = {"foo":"bar","baz":"qux"}; present(resource);
|
var resource = {"foo":"bar","baz":"qux"}; present(resource);
|
||||||
|
|
||||||
|
=== Plantillas WLang
|
||||||
|
|
||||||
|
Dependencias:: {wlang}[https://github.com/blambeau/wlang/]
|
||||||
|
Extensiones de Archivo:: <tt>.wlang</tt>
|
||||||
|
Ejemplo:: <tt>wlang :index, :locals => { :clave => 'valor' }</tt>
|
||||||
|
|
||||||
|
Como no vas a poder llamar a métodos de Ruby (excepto por +yield+) desde una
|
||||||
|
plantilla WLang, casi siempre vas a querer pasarle locales.
|
||||||
|
|
||||||
=== Plantillas Embebidas
|
=== Plantillas Embebidas
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
|
@ -1349,10 +1358,10 @@ Podés acceder a estas opciones utilizando el método <tt>settings</tt>:
|
||||||
=== Configurando la Protección de Ataques
|
=== Configurando la Protección de Ataques
|
||||||
|
|
||||||
Sinatra usa {Rack::Protection}[https://github.com/rkh/rack-protection#readme]
|
Sinatra usa {Rack::Protection}[https://github.com/rkh/rack-protection#readme]
|
||||||
para defender a tu aplicación de los ataques más comunes. Tenés que tener en
|
para defender a tu aplicación de los ataques más comunes. Si por algún motivo,
|
||||||
cuenta que como consecuencia de esto puede venir asociada una disminución del
|
querés desactivar esta funcionalidad, podés hacerlo como se indica a
|
||||||
rendimiento de tu aplicación. Si por este, o algún otro motivo, querés
|
continuación (tené en cuenta que tu aplicación va a quedar expuesta a un
|
||||||
desactivar está funcionalidad, podés hacerlo:
|
montón de vulnerabilidades bien conocidas):
|
||||||
|
|
||||||
disable :protection
|
disable :protection
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
= Sinatra
|
= Sinatra
|
||||||
|
|
||||||
<i>Attention : Ce document correspond à la traduction de la version anglaise et
|
<i>Attention : Ce document correspond à la traduction de la version anglaise et
|
||||||
il n'est peut être plus à jour.</i>
|
il n'est peut être plus à jour.</i>
|
||||||
|
|
||||||
|
|
91
README.rdoc
91
README.rdoc
|
@ -251,7 +251,7 @@ Use the <tt>:static_cache_control</tt> setting (see below) to add
|
||||||
|
|
||||||
== Views / Templates
|
== Views / Templates
|
||||||
|
|
||||||
Each template language is exposed as via its own rendering method. These
|
Each template language is exposed via its own rendering method. These
|
||||||
methods simply return a string:
|
methods simply return a string:
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
|
@ -755,7 +755,7 @@ middleware of choice as you would any other middleware:
|
||||||
end
|
end
|
||||||
|
|
||||||
To improve security, the session data in the cookie is signed with a session
|
To improve security, the session data in the cookie is signed with a session
|
||||||
secret. A random secret is generate for you by Sinatra. However, since this
|
secret. A random secret is generated for you by Sinatra. However, since this
|
||||||
secret will change with every start of your application, you might want to
|
secret will change with every start of your application, you might want to
|
||||||
set the secret yourself, so all your application instances share it:
|
set the secret yourself, so all your application instances share it:
|
||||||
|
|
||||||
|
@ -882,15 +882,15 @@ creating your own wrapper:
|
||||||
|
|
||||||
This allows you to implement streaming APIs,
|
This allows you to implement streaming APIs,
|
||||||
{Server Sent Events}[http://dev.w3.org/html5/eventsource/] and can be used as
|
{Server Sent Events}[http://dev.w3.org/html5/eventsource/] and can be used as
|
||||||
basis for {WebSockets}[http://en.wikipedia.org/wiki/WebSocket]. It can also be
|
the basis for {WebSockets}[http://en.wikipedia.org/wiki/WebSocket]. It can also be
|
||||||
used to increase throughput if some but not all content depends on a slow
|
used to increase throughput if some but not all content depends on a slow
|
||||||
resource.
|
resource.
|
||||||
|
|
||||||
Note that the streaming behavior, especially the number of concurrent request,
|
Note that the streaming behavior, especially the number of concurrent requests,
|
||||||
highly depends on the web server used to serve the application. Some servers,
|
highly depends on the web server used to serve the application. Some servers,
|
||||||
like WEBRick, might not even support streaming at all. If the server does not
|
like WEBRick, might not even support streaming at all. If the server does not
|
||||||
support streaming, the body will be sent all at once after the block passed to
|
support streaming, the body will be sent all at once after the block passed to
|
||||||
+stream+ finished executing. Streaming does not work at all with Shotgun.
|
+stream+ finishes executing. Streaming does not work at all with Shotgun.
|
||||||
|
|
||||||
If the optional parameter is set to +keep_open+, it will not call +close+ on
|
If the optional parameter is set to +keep_open+, it will not call +close+ on
|
||||||
the stream object, allowing you to close it at any later point in the
|
the stream object, allowing you to close it at any later point in the
|
||||||
|
@ -1012,7 +1012,7 @@ Or use a session:
|
||||||
|
|
||||||
Setting your headers correctly is the foundation for proper HTTP caching.
|
Setting your headers correctly is the foundation for proper HTTP caching.
|
||||||
|
|
||||||
You can easily set the Cache-Control header with like this:
|
You can easily set the Cache-Control header like this:
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
cache_control :public
|
cache_control :public
|
||||||
|
@ -1033,7 +1033,7 @@ If you are using the +expires+ helper to set the corresponding header,
|
||||||
end
|
end
|
||||||
|
|
||||||
To properly use caches, you should consider using +etag+ or +last_modified+.
|
To properly use caches, you should consider using +etag+ or +last_modified+.
|
||||||
It is recommended to call those helpers *before* doing heavy lifting, as they
|
It is recommended to call those helpers *before* doing any heavy lifting, as they
|
||||||
will immediately flush a response if the client already has the current
|
will immediately flush a response if the client already has the current
|
||||||
version in its cache:
|
version in its cache:
|
||||||
|
|
||||||
|
@ -1092,7 +1092,7 @@ For sending files, you can use the <tt>send_file</tt> helper method:
|
||||||
send_file 'foo.png'
|
send_file 'foo.png'
|
||||||
end
|
end
|
||||||
|
|
||||||
It also takes a couple of options:
|
It also takes options:
|
||||||
|
|
||||||
send_file 'foo.png', :type => :jpg
|
send_file 'foo.png', :type => :jpg
|
||||||
|
|
||||||
|
@ -1193,8 +1193,8 @@ You can also pass it a file name:
|
||||||
|
|
||||||
=== Dealing with Date and Time
|
=== Dealing with Date and Time
|
||||||
|
|
||||||
Sinatra offers a +time_for+ helper method, which, from the given value
|
Sinatra offers a +time_for+ helper method that generates a Time object
|
||||||
generates a Time object. It is also able to convert +DateTime+, +Date+ and
|
from the given value. It is also able to convert +DateTime+, +Date+ and
|
||||||
similar classes:
|
similar classes:
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
|
@ -1315,7 +1315,7 @@ You can access those options via <tt>settings</tt>:
|
||||||
Sinatra is using
|
Sinatra is using
|
||||||
{Rack::Protection}[https://github.com/rkh/rack-protection#readme] to defend
|
{Rack::Protection}[https://github.com/rkh/rack-protection#readme] to defend
|
||||||
you application against common, opportunistic attacks. You can easily disable
|
you application against common, opportunistic attacks. You can easily disable
|
||||||
this behavior (which will open your application to tons of common
|
this behavior (which will open up your application to tons of common
|
||||||
vulnerabilities):
|
vulnerabilities):
|
||||||
|
|
||||||
disable :protection
|
disable :protection
|
||||||
|
@ -1337,7 +1337,7 @@ You can also hand in an array in order to disable a list of protections:
|
||||||
Enable if your app is running behind a reverse proxy that
|
Enable if your app is running behind a reverse proxy that
|
||||||
has not been set up properly. Note that the +url+ helper
|
has not been set up properly. Note that the +url+ helper
|
||||||
will still produce absolute URLs, unless you pass in
|
will still produce absolute URLs, unless you pass in
|
||||||
+false+ as second parameter.
|
+false+ as the second parameter.
|
||||||
|
|
||||||
Disabled per default.
|
Disabled per default.
|
||||||
|
|
||||||
|
@ -1410,16 +1410,19 @@ You can also hand in an array in order to disable a list of protections:
|
||||||
defaults to ['thin', 'mongrel', 'webrick'], order
|
defaults to ['thin', 'mongrel', 'webrick'], order
|
||||||
indicates priority.
|
indicates priority.
|
||||||
|
|
||||||
[sessions] enable cookie based sessions support using
|
[sessions] enable cookie-based sessions support using
|
||||||
<tt>Rack::Session::Cookie</tt>. See 'Using Sessions'
|
<tt>Rack::Session::Cookie</tt>. See 'Using Sessions'
|
||||||
section for more information.
|
section for more information.
|
||||||
|
|
||||||
[show_exceptions] show a stack trace in the browser when an exception
|
[show_exceptions] show a stack trace in the browser when an exception
|
||||||
happens. Enabled by default when <tt>environment</tt>
|
happens. Enabled by default when <tt>environment</tt>
|
||||||
is set to <tt>"development"</tt>, disabled otherwise.
|
is set to <tt>"development"</tt>, disabled otherwise.
|
||||||
|
Can also be set to <tt>:after_handler</tt> to trigger
|
||||||
|
app-specified error handling before showing a stack
|
||||||
|
trace in the browser.
|
||||||
|
|
||||||
[static] Whether Sinatra should handle serving static files.
|
[static] Whether Sinatra should handle serving static files.
|
||||||
Disable when using a Server able to do this on its own.
|
Disable when using a server able to do this on its own.
|
||||||
Disabling will boost performance.
|
Disabling will boost performance.
|
||||||
Enabled per default in classic style, disabled for
|
Enabled per default in classic style, disabled for
|
||||||
modular apps.
|
modular apps.
|
||||||
|
@ -1441,17 +1444,17 @@ You can also hand in an array in order to disable a list of protections:
|
||||||
There are three predefined +environments+: <tt>"development"</tt>,
|
There are three predefined +environments+: <tt>"development"</tt>,
|
||||||
<tt>"production"</tt> and <tt>"test"</tt>. Environments can be set
|
<tt>"production"</tt> and <tt>"test"</tt>. Environments can be set
|
||||||
through the +RACK_ENV+ environment variable. The default value is
|
through the +RACK_ENV+ environment variable. The default value is
|
||||||
<tt>"development"</tt>. In this mode, all templates are reloaded between
|
<tt>"development"</tt>. In the <tt>"development"</tt> environment all templates are reloaded between
|
||||||
requests. Special <tt>not_found</tt> and <tt>error</tt> handlers are installed
|
requests, and special <tt>not_found</tt> and <tt>error</tt> handlers
|
||||||
for this environment so you will see a stack trace in your browser.
|
display stack traces in your browser.
|
||||||
In <tt>"production"</tt> and <tt>"test"</tt> templates are cached by default.
|
In the <tt>"production"</tt> and <tt>"test"</tt> environments, templates are cached by default.
|
||||||
|
|
||||||
To run different environments use the <tt>-e</tt> option:
|
To run different environments use the <tt>-e</tt> option:
|
||||||
|
|
||||||
ruby my_app.rb -e [ENVIRONMENT]
|
ruby my_app.rb -e [ENVIRONMENT]
|
||||||
|
|
||||||
You can use predefined methods: +development?+, +test?+ and +production?+ to
|
You can use predefined methods: +development?+, +test?+ and +production?+ to
|
||||||
check which enviroment is currently set.
|
check the current environment setting.
|
||||||
|
|
||||||
== Error Handling
|
== Error Handling
|
||||||
|
|
||||||
|
@ -1608,7 +1611,7 @@ directories, logging, exception detail page, etc.). That's where
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
The methods available to <tt>Sinatra::Base</tt> subclasses are exactly as those
|
The methods available to <tt>Sinatra::Base</tt> subclasses are exactly the same as those
|
||||||
available via the top-level DSL. Most top-level apps can be converted to
|
available via the top-level DSL. Most top-level apps can be converted to
|
||||||
<tt>Sinatra::Base</tt> components with two modifications:
|
<tt>Sinatra::Base</tt> components with two modifications:
|
||||||
|
|
||||||
|
@ -1625,13 +1628,13 @@ for details on available options and their behavior.
|
||||||
|
|
||||||
=== Modular vs. Classic Style
|
=== Modular vs. Classic Style
|
||||||
|
|
||||||
Contrary to common belief, there is nothing wrong with classic style. If it
|
Contrary to common belief, there is nothing wrong with the classic style. If it
|
||||||
suits your application, you do not have to switch to a modular application.
|
suits your application, you do not have to switch to a modular application.
|
||||||
|
|
||||||
The main downsides of using classic style rather than modular style is that
|
The main disadvantage of using the classic style rather than the modular style is that
|
||||||
you may only have one Sinatra application per Ruby process. If you plan to use
|
you will only have one Sinatra application per Ruby process. If you plan to use
|
||||||
more than one, switch to modular style. There is no reason you cannot mix
|
more than one, switch to the modular style. There is no reason you cannot mix
|
||||||
modular and classic style.
|
the modular and the classic styles.
|
||||||
|
|
||||||
If switching from one style to the other, you should be aware of slightly
|
If switching from one style to the other, you should be aware of slightly
|
||||||
different default settings:
|
different default settings:
|
||||||
|
@ -1665,7 +1668,7 @@ Start with:
|
||||||
|
|
||||||
ruby my_app.rb
|
ruby my_app.rb
|
||||||
|
|
||||||
Or with a <tt>config.ru</tt>, which allows using any Rack handler:
|
Or with a <tt>config.ru</tt> file, which allows using any Rack handler:
|
||||||
|
|
||||||
# config.ru
|
# config.ru
|
||||||
require './my_app'
|
require './my_app'
|
||||||
|
@ -1693,15 +1696,15 @@ And a corresponding <tt>config.ru</tt>:
|
||||||
|
|
||||||
=== When to use a config.ru?
|
=== When to use a config.ru?
|
||||||
|
|
||||||
Good signs you probably want to use a <tt>config.ru</tt>:
|
A <tt>config.ru</tt> file is recommended if:
|
||||||
|
|
||||||
* You want to deploy with a different Rack handler (Passenger, Unicorn,
|
* You want to deploy with a different Rack handler (Passenger, Unicorn,
|
||||||
Heroku, ...).
|
Heroku, ...).
|
||||||
* You want to use more than one subclass of <tt>Sinatra::Base</tt>.
|
* You want to use more than one subclass of <tt>Sinatra::Base</tt>.
|
||||||
* You want to use Sinatra only for middleware, but not as endpoint.
|
* You want to use Sinatra only for middleware, and not as an endpoint.
|
||||||
|
|
||||||
<b>There is no need to switch to a <tt>config.ru</tt> only because you
|
<b>There is no need to switch to a <tt>config.ru</tt> simply because you
|
||||||
switched to modular style, and you don't have to use modular style for running
|
switched to the modular style, and you don't have to use the modular style for running
|
||||||
with a <tt>config.ru</tt>.</b>
|
with a <tt>config.ru</tt>.</b>
|
||||||
|
|
||||||
=== Using Sinatra as Middleware
|
=== Using Sinatra as Middleware
|
||||||
|
@ -1749,7 +1752,7 @@ assign them to a constant, you can do this with <tt>Sinatra.new</tt>:
|
||||||
my_app = Sinatra.new { get('/') { "hi" } }
|
my_app = Sinatra.new { get('/') { "hi" } }
|
||||||
my_app.run!
|
my_app.run!
|
||||||
|
|
||||||
It takes the application to inherit from as optional argument:
|
It takes the application to inherit from as an optional argument:
|
||||||
|
|
||||||
# config.ru
|
# config.ru
|
||||||
require 'sinatra/base'
|
require 'sinatra/base'
|
||||||
|
@ -1791,7 +1794,7 @@ Every Sinatra application corresponds to a subclass of <tt>Sinatra::Base</tt>.
|
||||||
If you are using the top-level DSL (<tt>require 'sinatra'</tt>), then this
|
If you are using the top-level DSL (<tt>require 'sinatra'</tt>), then this
|
||||||
class is <tt>Sinatra::Application</tt>, otherwise it is the subclass you
|
class is <tt>Sinatra::Application</tt>, otherwise it is the subclass you
|
||||||
created explicitly. At class level you have methods like +get+ or +before+, but
|
created explicitly. At class level you have methods like +get+ or +before+, but
|
||||||
you cannot access the +request+ object or the +session+, as there only is a
|
you cannot access the +request+ or +session+ objects, as there is only a
|
||||||
single application class for all requests.
|
single application class for all requests.
|
||||||
|
|
||||||
Options created via +set+ are methods at class level:
|
Options created via +set+ are methods at class level:
|
||||||
|
@ -1817,13 +1820,13 @@ You have the application scope binding inside:
|
||||||
You can reach the scope object (the class) like this:
|
You can reach the scope object (the class) like this:
|
||||||
|
|
||||||
* Via the object passed to configure blocks (<tt>configure { |c| ... }</tt>)
|
* Via the object passed to configure blocks (<tt>configure { |c| ... }</tt>)
|
||||||
* +settings+ from within request scope
|
* +settings+ from within the request scope
|
||||||
|
|
||||||
=== Request/Instance Scope
|
=== Request/Instance Scope
|
||||||
|
|
||||||
For every incoming request, a new instance of your application class is
|
For every incoming request, a new instance of your application class is
|
||||||
created and all handler blocks run in that scope. From within this scope you
|
created and all handler blocks run in that scope. From within this scope you
|
||||||
can access the +request+ and +session+ object or call rendering methods like
|
can access the +request+ and +session+ objects or call rendering methods like
|
||||||
+erb+ or +haml+. You can access the application scope from within the request
|
+erb+ or +haml+. You can access the application scope from within the request
|
||||||
scope via the +settings+ helper:
|
scope via the +settings+ helper:
|
||||||
|
|
||||||
|
@ -1852,8 +1855,8 @@ You have the request scope binding inside:
|
||||||
=== Delegation Scope
|
=== Delegation Scope
|
||||||
|
|
||||||
The delegation scope just forwards methods to the class scope. However, it
|
The delegation scope just forwards methods to the class scope. However, it
|
||||||
does not behave 100% like the class scope, as you do not have the class
|
does not behave exactly like the class scope, as you do not have the class
|
||||||
binding. Only methods explicitly marked for delegation are available and you
|
binding. Only methods explicitly marked for delegation are available, and you
|
||||||
do not share variables/state with the class scope (read: you have a different
|
do not share variables/state with the class scope (read: you have a different
|
||||||
+self+). You can explicitly add method delegations by calling
|
+self+). You can explicitly add method delegations by calling
|
||||||
<tt>Sinatra::Delegator.delegate :method_name</tt>.
|
<tt>Sinatra::Delegator.delegate :method_name</tt>.
|
||||||
|
@ -1889,14 +1892,14 @@ The following Ruby versions are officially supported:
|
||||||
[ Ruby 1.8.7 ]
|
[ Ruby 1.8.7 ]
|
||||||
1.8.7 is fully supported, however, if nothing is keeping you from it, we
|
1.8.7 is fully supported, however, if nothing is keeping you from it, we
|
||||||
recommend upgrading to 1.9.2 or switching to JRuby or Rubinius. Support for
|
recommend upgrading to 1.9.2 or switching to JRuby or Rubinius. Support for
|
||||||
1.8.7 will not be dropped before Sinatra 2.0 and Ruby 2.0 except maybe for
|
1.8.7 will not be dropped before Sinatra 2.0 and Ruby 2.0 except maybe in
|
||||||
the unlikely event of 1.8.8 being released. Even then, we might continue
|
the unlikely event of 1.8.8 being released. Even then, we might continue
|
||||||
supporting it. <b>Ruby 1.8.6 is no longer supported.</b> If you want to run
|
supporting it. <b>Ruby 1.8.6 is no longer supported.</b> If you want to run
|
||||||
with 1.8.6, downgrade to Sinatra 1.2, which will receive bug fixes until
|
with 1.8.6, downgrade to Sinatra 1.2, which will receive bug fixes until
|
||||||
Sinatra 1.4.0 is released.
|
Sinatra 1.4.0 is released.
|
||||||
|
|
||||||
[ Ruby 1.9.2 ]
|
[ Ruby 1.9.2 ]
|
||||||
1.9.2 is fully supported and recommended. Do not use 1.9.2p0, it is known to
|
1.9.2 is fully supported and recommended. Do not use 1.9.2p0, as it is known to
|
||||||
cause segmentation faults when running Sinatra. Support will continue at least
|
cause segmentation faults when running Sinatra. Support will continue at least
|
||||||
until the release of Ruby 1.9.4/2.0 and support for the latest 1.9 release
|
until the release of Ruby 1.9.4/2.0 and support for the latest 1.9 release
|
||||||
will continue as long as it is still supported by the Ruby core team.
|
will continue as long as it is still supported by the Ruby core team.
|
||||||
|
@ -1906,8 +1909,8 @@ The following Ruby versions are officially supported:
|
||||||
from an earlier version will invalidate all sessions.
|
from an earlier version will invalidate all sessions.
|
||||||
|
|
||||||
[ Rubinius ]
|
[ Rubinius ]
|
||||||
Rubinius is officially supported (Rubinius >= 1.2.4), everything, including
|
Rubinius is officially supported (Rubinius >= 1.2.4), everything works, including
|
||||||
all template languages, works. The upcoming 2.0 release is supported as
|
all template languages. The upcoming 2.0 release is supported as
|
||||||
well, including 1.9 mode.
|
well, including 1.9 mode.
|
||||||
|
|
||||||
[ JRuby ]
|
[ JRuby ]
|
||||||
|
@ -1938,12 +1941,12 @@ both 1.9.4p0 and 2.0.0p0 to be supported.
|
||||||
Sinatra should work on any operating system supported by the chosen Ruby
|
Sinatra should work on any operating system supported by the chosen Ruby
|
||||||
implementation.
|
implementation.
|
||||||
|
|
||||||
You will not be able to run Sinatra on Cardinal, SmallRuby, BlueRuby or any
|
Sinatra currently doesn't run on Cardinal, SmallRuby, BlueRuby or any
|
||||||
Ruby version prior to 1.8.7 as of the time being.
|
Ruby version prior to 1.8.7.
|
||||||
|
|
||||||
== The Bleeding Edge
|
== The Bleeding Edge
|
||||||
|
|
||||||
If you would like to use Sinatra's latest bleeding code, feel free to run your
|
If you would like to use Sinatra's latest bleeding-edge code, feel free to run your
|
||||||
application against the master branch, it should be rather stable.
|
application against the master branch, it should be rather stable.
|
||||||
|
|
||||||
We also push out prerelease gems from time to time, so you can do a
|
We also push out prerelease gems from time to time, so you can do a
|
||||||
|
@ -1970,7 +1973,7 @@ Then, in your project directory, create a +Gemfile+:
|
||||||
gem 'haml' # for instance, if you use haml
|
gem 'haml' # for instance, if you use haml
|
||||||
gem 'activerecord', '~> 3.0' # maybe you also need ActiveRecord 3.x
|
gem 'activerecord', '~> 3.0' # maybe you also need ActiveRecord 3.x
|
||||||
|
|
||||||
Note that you will have to list all your applications dependencies in there.
|
Note that you will have to list all your application's dependencies in the +Gemfile+.
|
||||||
Sinatra's direct dependencies (Rack and Tilt) will, however, be automatically
|
Sinatra's direct dependencies (Rack and Tilt) will, however, be automatically
|
||||||
fetched and added by Bundler.
|
fetched and added by Bundler.
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ Thin — это более производительный и функцион
|
||||||
Маршруты сверяются с запросом в порядке очередности их записи в файле приложения.
|
Маршруты сверяются с запросом в порядке очередности их записи в файле приложения.
|
||||||
Первый же совпавший с запросом маршрут и будет вызван.
|
Первый же совпавший с запросом маршрут и будет вызван.
|
||||||
|
|
||||||
Шаблоны маршрутов могут включать в себя именные параметры доступные
|
Шаблоны маршрутов могут включать в себя именованные параметры доступные
|
||||||
в xэше <tt>params</tt>:
|
в xэше <tt>params</tt>:
|
||||||
|
|
||||||
get '/hello/:name' do
|
get '/hello/:name' do
|
||||||
|
@ -65,7 +65,7 @@ Thin — это более производительный и функцион
|
||||||
"Hello #{params[:name]}!"
|
"Hello #{params[:name]}!"
|
||||||
end
|
end
|
||||||
|
|
||||||
Также можно использовать именные параметры в качестве переменных
|
Также можно использовать именованные параметры в качестве переменных
|
||||||
блока:
|
блока:
|
||||||
|
|
||||||
get '/hello/:name' do |n|
|
get '/hello/:name' do |n|
|
||||||
|
@ -117,7 +117,7 @@ Thin — это более производительный и функцион
|
||||||
=== Условия
|
=== Условия
|
||||||
|
|
||||||
Маршруты могут включать различные условия совпадений, например,
|
Маршруты могут включать различные условия совпадений, например,
|
||||||
клиентской приложение (user agent):
|
клиентское приложение (user agent):
|
||||||
|
|
||||||
get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
|
get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
|
||||||
"You're using Songbird version #{params[:agent][0]}"
|
"You're using Songbird version #{params[:agent][0]}"
|
||||||
|
@ -544,6 +544,15 @@ Thin — это более производительный и функцион
|
||||||
|
|
||||||
var resource = {"foo":"bar","baz":"qux"}; present(resource);
|
var resource = {"foo":"bar","baz":"qux"}; present(resource);
|
||||||
|
|
||||||
|
=== WLang шаблоны
|
||||||
|
|
||||||
|
Зависимости:: {wlang}[https://github.com/blambeau/wlang/]
|
||||||
|
Расширения файлов:: <tt>.wlang</tt>
|
||||||
|
Пример:: <tt>wlang :index, :locals => { :key => 'value' }</tt>
|
||||||
|
|
||||||
|
Так как в WLang шаблонах невозможно вызывать методы из Ruby напрямую (за исключением +yield+), то
|
||||||
|
вы почти всегда будете передавать в шаблон локальные переменные.
|
||||||
|
|
||||||
=== Встроенные шаблоны
|
=== Встроенные шаблоны
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
|
@ -594,7 +603,7 @@ Thin — это более производительный и функцион
|
||||||
загружены автоматически. Вызовите <tt>enable :inline_templates</tt> напрямую, если
|
загружены автоматически. Вызовите <tt>enable :inline_templates</tt> напрямую, если
|
||||||
используете вложенные шаблоны в других файлах.
|
используете вложенные шаблоны в других файлах.
|
||||||
|
|
||||||
=== Именные шаблоны
|
=== Именованные шаблоны
|
||||||
|
|
||||||
Шаблоны также могут быть определены при помощи <tt>template</tt> метода:
|
Шаблоны также могут быть определены при помощи <tt>template</tt> метода:
|
||||||
|
|
||||||
|
@ -1314,7 +1323,7 @@ Sinatra предлагает метод-помощник +time_for+, котор
|
||||||
Sinatra использует
|
Sinatra использует
|
||||||
{Rack::Protection}[https://github.com/rkh/rack-protection#readme] для
|
{Rack::Protection}[https://github.com/rkh/rack-protection#readme] для
|
||||||
защиты приложения от простых атак. Вы можете легко выключить эту
|
защиты приложения от простых атак. Вы можете легко выключить эту
|
||||||
защиту (что даст прирост в производительности):
|
защиту (что сделает ваше приложение чрезвычайно уязвимым):
|
||||||
|
|
||||||
disable :protection
|
disable :protection
|
||||||
|
|
||||||
|
@ -1411,6 +1420,9 @@ Sinatra использует
|
||||||
|
|
||||||
[show_exceptions] показывать исключения/стек вызовов (stack trace) в браузере.
|
[show_exceptions] показывать исключения/стек вызовов (stack trace) в браузере.
|
||||||
По умолчанию включено только в окружении <tt>development</tt>.
|
По умолчанию включено только в окружении <tt>development</tt>.
|
||||||
|
Может быть установлено в <tt>:after_handler</tt> для запуска специфичной
|
||||||
|
для приложения обработки ошибок, прежде чем показывать трассировку
|
||||||
|
стека в браузере.
|
||||||
|
|
||||||
[static] должна ли Sinatra осуществлять раздачу статических файлов.
|
[static] должна ли Sinatra осуществлять раздачу статических файлов.
|
||||||
Отключите, когда используете какой-либо веб-сервер для этой цели.
|
Отключите, когда используете какой-либо веб-сервер для этой цели.
|
||||||
|
|
|
@ -25,11 +25,11 @@ __END__
|
||||||
|
|
||||||
@@ layout
|
@@ layout
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Super Simple Chat with Sinatra</title>
|
<title>Super Simple Chat with Sinatra</title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body><%= yield %></body>
|
<body><%= yield %></body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -58,4 +58,4 @@ __END__
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<input id='msg' placeholder='type message here...' />
|
<input id='msg' placeholder='type message here...' />
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# external dependencies
|
# external dependencies
|
||||||
require 'rack'
|
require 'rack'
|
||||||
require 'tilt'
|
require 'tilt'
|
||||||
require "rack/protection"
|
require 'rack/protection'
|
||||||
|
|
||||||
# stdlib dependencies
|
# stdlib dependencies
|
||||||
require 'thread'
|
require 'thread'
|
||||||
|
@ -1314,17 +1314,21 @@ module Sinatra
|
||||||
def compile(path)
|
def compile(path)
|
||||||
keys = []
|
keys = []
|
||||||
if path.respond_to? :to_str
|
if path.respond_to? :to_str
|
||||||
pattern = path.to_str.gsub(/[^\?\%\\\/\:\*\w]/) { |c| encoded(c) }
|
ignore = ""
|
||||||
|
pattern = path.to_str.gsub(/[^\?\%\\\/\:\*\w]/) do |c|
|
||||||
|
ignore << escaped(c).join if c.match(/[\.@]/)
|
||||||
|
encoded(c)
|
||||||
|
end
|
||||||
pattern.gsub!(/((:\w+)|\*)/) do |match|
|
pattern.gsub!(/((:\w+)|\*)/) do |match|
|
||||||
if match == "*"
|
if match == "*"
|
||||||
keys << 'splat'
|
keys << 'splat'
|
||||||
"(.*?)"
|
"(.*?)"
|
||||||
else
|
else
|
||||||
keys << $2[1..-1]
|
keys << $2[1..-1]
|
||||||
"([^/?#]+)"
|
"([^#{ignore}/?#]+)"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
[/^#{pattern}$/, keys]
|
[/\A#{pattern}\z/, keys]
|
||||||
elsif path.respond_to?(:keys) && path.respond_to?(:match)
|
elsif path.respond_to?(:keys) && path.respond_to?(:match)
|
||||||
[path, path.keys]
|
[path, path.keys]
|
||||||
elsif path.respond_to?(:names) && path.respond_to?(:match)
|
elsif path.respond_to?(:names) && path.respond_to?(:match)
|
||||||
|
@ -1340,11 +1344,15 @@ module Sinatra
|
||||||
|
|
||||||
def encoded(char)
|
def encoded(char)
|
||||||
enc = URI.escape(char)
|
enc = URI.escape(char)
|
||||||
enc = "(?:#{Regexp.escape enc}|#{URI.escape char, /./})" if enc == char
|
enc = "(?:#{escaped(char, enc).join('|')})" if enc == char
|
||||||
enc = "(?:#{enc}|#{encoded('+')})" if char == " "
|
enc = "(?:#{enc}|#{encoded('+')})" if char == " "
|
||||||
enc
|
enc
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def escaped(char, enc = URI.escape(char))
|
||||||
|
[Regexp.escape(enc), URI.escape(char, /./)]
|
||||||
|
end
|
||||||
|
|
||||||
public
|
public
|
||||||
# Makes the methods defined in the block and in the Modules given
|
# Makes the methods defined in the block and in the Modules given
|
||||||
# in `extensions` available to the handlers and templates
|
# in `extensions` available to the handlers and templates
|
||||||
|
|
|
@ -10,7 +10,7 @@ Gem::Specification.new 'sinatra', Sinatra::VERSION do |s|
|
||||||
s.files = `git ls-files`.split("\n") - %w[.gitignore .travis.yml]
|
s.files = `git ls-files`.split("\n") - %w[.gitignore .travis.yml]
|
||||||
s.test_files = s.files.select { |p| p =~ /^test\/.*_test.rb/ }
|
s.test_files = s.files.select { |p| p =~ /^test\/.*_test.rb/ }
|
||||||
s.extra_rdoc_files = s.files.select { |p| p =~ /^README/ } << 'LICENSE'
|
s.extra_rdoc_files = s.files.select { |p| p =~ /^README/ } << 'LICENSE'
|
||||||
s.rdoc_options = %w[--line-numbers --inline-source --title Sinatra --main README.rdoc]
|
s.rdoc_options = %w[--line-numbers --inline-source --title Sinatra --main README.rdoc --encoding=UTF-8]
|
||||||
|
|
||||||
s.add_dependency 'rack', '~> 1.3', '>= 1.3.6'
|
s.add_dependency 'rack', '~> 1.3', '>= 1.3.6'
|
||||||
s.add_dependency 'rack-protection', '~> 1.2'
|
s.add_dependency 'rack-protection', '~> 1.2'
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
# I like coding: UTF-8
|
||||||
|
require File.expand_path('../helper', __FILE__)
|
||||||
|
|
||||||
|
class CompileTest < Test::Unit::TestCase
|
||||||
|
|
||||||
|
def self.converts pattern, expected_regexp
|
||||||
|
it "generates #{expected_regexp.source} from #{pattern}" do
|
||||||
|
compiled, _ = compiled pattern
|
||||||
|
assert_equal expected_regexp, compiled
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def self.parses pattern, example, expected_params
|
||||||
|
it "parses #{example} with #{pattern} into params #{expected_params}" do
|
||||||
|
compiled, keys = compiled pattern
|
||||||
|
match = compiled.match(example)
|
||||||
|
fail %Q{"#{example}" does not parse on pattern "#{pattern}".} unless match
|
||||||
|
|
||||||
|
# Aggregate e.g. multiple splat values into one array.
|
||||||
|
#
|
||||||
|
params = keys.zip(match.captures).reduce({}) do |hash, mapping|
|
||||||
|
key, value = mapping
|
||||||
|
hash[key] = if existing = hash[key]
|
||||||
|
existing.respond_to?(:to_ary) ? existing << value : [existing, value]
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
|
hash
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal(expected_params, params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def self.fails pattern, example
|
||||||
|
it "does not parse #{example} with #{pattern}" do
|
||||||
|
compiled, _ = compiled pattern
|
||||||
|
match = compiled.match(example)
|
||||||
|
fail %Q{"#{pattern}" does parse "#{example}" but it should fail} if match
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def compiled pattern
|
||||||
|
app ||= mock_app {}
|
||||||
|
compiled, keys = app.send(:compile, pattern)
|
||||||
|
[compiled, keys]
|
||||||
|
end
|
||||||
|
|
||||||
|
converts "/", %r{\A/\z}
|
||||||
|
parses "/", "/", {}
|
||||||
|
|
||||||
|
converts "/foo", %r{\A/foo\z}
|
||||||
|
parses "/foo", "/foo", {}
|
||||||
|
|
||||||
|
converts "/:foo", %r{\A/([^/?#]+)\z}
|
||||||
|
parses "/:foo", "/foo", "foo" => "foo"
|
||||||
|
parses "/:foo", "/foo.bar", "foo" => "foo.bar"
|
||||||
|
parses "/:foo", "/foo%2Fbar", "foo" => "foo%2Fbar"
|
||||||
|
fails "/:foo", "/foo?"
|
||||||
|
fails "/:foo", "/foo/bar"
|
||||||
|
fails "/:foo", "/"
|
||||||
|
fails "/:foo", "/foo/"
|
||||||
|
|
||||||
|
converts "/föö", %r{\A/f%C3%B6%C3%B6\z}
|
||||||
|
parses "/föö", "/f%C3%B6%C3%B6", {}
|
||||||
|
|
||||||
|
converts "/:foo/:bar", %r{\A/([^/?#]+)/([^/?#]+)\z}
|
||||||
|
parses "/:foo/:bar", "/foo/bar", "foo" => "foo", "bar" => "bar"
|
||||||
|
|
||||||
|
converts "/hello/:person", %r{\A/hello/([^/?#]+)\z}
|
||||||
|
parses "/hello/:person", "/hello/Frank", "person" => "Frank"
|
||||||
|
|
||||||
|
converts "/?:foo?/?:bar?", %r{\A/?([^/?#]+)?/?([^/?#]+)?\z}
|
||||||
|
parses "/?:foo?/?:bar?", "/hello/world", "foo" => "hello", "bar" => "world"
|
||||||
|
parses "/?:foo?/?:bar?", "/hello", "foo" => "hello", "bar" => nil
|
||||||
|
parses "/?:foo?/?:bar?", "/", "foo" => nil, "bar" => nil
|
||||||
|
parses "/?:foo?/?:bar?", "", "foo" => nil, "bar" => nil
|
||||||
|
|
||||||
|
converts "/*", %r{\A/(.*?)\z}
|
||||||
|
parses "/*", "/", "splat" => ""
|
||||||
|
parses "/*", "/foo", "splat" => "foo"
|
||||||
|
parses "/*", "/foo/bar", "splat" => "foo/bar"
|
||||||
|
|
||||||
|
converts "/:foo/*", %r{\A/([^/?#]+)/(.*?)\z}
|
||||||
|
parses "/:foo/*", "/foo/bar/baz", "foo" => "foo", "splat" => "bar/baz"
|
||||||
|
|
||||||
|
converts "/:foo/:bar", %r{\A/([^/?#]+)/([^/?#]+)\z}
|
||||||
|
parses "/:foo/:bar", "/user@example.com/name", "foo" => "user@example.com", "bar" => "name"
|
||||||
|
|
||||||
|
converts "/test$/", %r{\A/test(?:\$|%24)/\z}
|
||||||
|
parses "/test$/", "/test$/", {}
|
||||||
|
|
||||||
|
converts "/te+st/", %r{\A/te(?:\+|%2B)st/\z}
|
||||||
|
parses "/te+st/", "/te+st/", {}
|
||||||
|
fails "/te+st/", "/test/"
|
||||||
|
fails "/te+st/", "/teeest/"
|
||||||
|
|
||||||
|
converts "/test(bar)/", %r{\A/test(?:\(|%28)bar(?:\)|%29)/\z}
|
||||||
|
parses "/test(bar)/", "/test(bar)/", {}
|
||||||
|
|
||||||
|
converts "/path with spaces", %r{\A/path(?:%20|(?:\+|%2B))with(?:%20|(?:\+|%2B))spaces\z}
|
||||||
|
parses "/path with spaces", "/path%20with%20spaces", {}
|
||||||
|
parses "/path with spaces", "/path%2Bwith%2Bspaces", {}
|
||||||
|
parses "/path with spaces", "/path+with+spaces", {}
|
||||||
|
|
||||||
|
converts "/foo&bar", %r{\A/foo(?:&|%26)bar\z}
|
||||||
|
parses "/foo&bar", "/foo&bar", {}
|
||||||
|
|
||||||
|
converts "/:foo/*", %r{\A/([^/?#]+)/(.*?)\z}
|
||||||
|
parses "/:foo/*", "/hello%20world/how%20are%20you", "foo" => "hello%20world", "splat" => "how%20are%20you"
|
||||||
|
|
||||||
|
converts "/*/foo/*/*", %r{\A/(.*?)/foo/(.*?)/(.*?)\z}
|
||||||
|
parses "/*/foo/*/*", "/bar/foo/bling/baz/boom", "splat" => ["bar", "bling", "baz/boom"]
|
||||||
|
fails "/*/foo/*/*", "/bar/foo/baz"
|
||||||
|
|
||||||
|
converts "/test.bar", %r{\A/test(?:\.|%2E)bar\z}
|
||||||
|
parses "/test.bar", "/test.bar", {}
|
||||||
|
fails "/test.bar", "/test0bar"
|
||||||
|
|
||||||
|
converts "/:file.:ext", %r{\A/([^\.%2E/?#]+)(?:\.|%2E)([^\.%2E/?#]+)\z}
|
||||||
|
parses "/:file.:ext", "/pony.jpg", "file" => "pony", "ext" => "jpg"
|
||||||
|
parses "/:file.:ext", "/pony%2Ejpg", "file" => "pony", "ext" => "jpg"
|
||||||
|
fails "/:file.:ext", "/.jpg"
|
||||||
|
|
||||||
|
converts "/:name.?:format?", %r{\A/([^\.%2E/?#]+)(?:\.|%2E)?([^\.%2E/?#]+)?\z}
|
||||||
|
parses "/:name.?:format?", "/foo", "name" => "foo", "format" => nil
|
||||||
|
parses "/:name.?:format?", "/foo.bar", "name" => "foo", "format" => "bar"
|
||||||
|
parses "/:name.?:format?", "/foo%2Ebar", "name" => "foo", "format" => "bar"
|
||||||
|
fails "/:name.?:format?", "/.bar"
|
||||||
|
|
||||||
|
converts "/:user@?:host?", %r{\A/([^@%40/?#]+)(?:@|%40)?([^@%40/?#]+)?\z}
|
||||||
|
parses "/:user@?:host?", "/foo@bar", "user" => "foo", "host" => "bar"
|
||||||
|
parses "/:user@?:host?", "/foo.foo@bar", "user" => "foo.foo", "host" => "bar"
|
||||||
|
parses "/:user@?:host?", "/foo@bar.bar", "user" => "foo", "host" => "bar.bar"
|
||||||
|
|
||||||
|
# From https://gist.github.com/2154980#gistcomment-169469.
|
||||||
|
#
|
||||||
|
# converts "/:name(.:format)?", %r{\A/([^\.%2E/?#]+)(?:\(|%28)(?:\.|%2E)([^\.%2E/?#]+)(?:\)|%29)?\z}
|
||||||
|
# parses "/:name(.:format)?", "/foo", "name" => "foo", "format" => nil
|
||||||
|
# parses "/:name(.:format)?", "/foo.bar", "name" => "foo", "format" => "bar"
|
||||||
|
fails "/:name(.:format)?", "/foo."
|
||||||
|
end
|
|
@ -1,15 +1,15 @@
|
||||||
# Copyright (c) 2009 Damian Janowski and Michel Martens for Citrusbyte
|
# Copyright (c) 2009 Damian Janowski and Michel Martens for Citrusbyte
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
# in the Software without restriction, including without limitation the rights
|
# in the Software without restriction, including without limitation the rights
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
# furnished to do so, subject to the following conditions:
|
# furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
# The above copyright notice and this permission notice shall be included in
|
# The above copyright notice and this permission notice shall be included in
|
||||||
# all copies or substantial portions of the Software.
|
# all copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
|
|
@ -586,21 +586,21 @@ class HelpersTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the Content-Type response header' do
|
it 'sets the Content-Type response header' do
|
||||||
attachment_app('test.xml')
|
attachment_app('test.xml')
|
||||||
get '/attachment'
|
get '/attachment'
|
||||||
assert_equal 'application/xml;charset=utf-8', response['Content-Type']
|
assert_equal 'application/xml;charset=utf-8', response['Content-Type']
|
||||||
assert_equal '<sinatra></sinatra>', body
|
assert_equal '<sinatra></sinatra>', body
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the Content-Type response header without extname' do
|
it 'sets the Content-Type response header without extname' do
|
||||||
attachment_app('test')
|
attachment_app('test')
|
||||||
get '/attachment'
|
get '/attachment'
|
||||||
assert_equal 'text/html;charset=utf-8', response['Content-Type']
|
assert_equal 'text/html;charset=utf-8', response['Content-Type']
|
||||||
assert_equal '<sinatra></sinatra>', body
|
assert_equal '<sinatra></sinatra>', body
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the Content-Type response header with extname' do
|
it 'sets the Content-Type response header with extname' do
|
||||||
mock_app do
|
mock_app do
|
||||||
get('/attachment') do
|
get('/attachment') do
|
||||||
|
@ -612,9 +612,9 @@ class HelpersTest < Test::Unit::TestCase
|
||||||
|
|
||||||
get '/attachment'
|
get '/attachment'
|
||||||
assert_equal 'application/atom+xml', response['Content-Type']
|
assert_equal 'application/atom+xml', response['Content-Type']
|
||||||
assert_equal '<sinatra></sinatra>', body
|
assert_equal '<sinatra></sinatra>', body
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'send_file' do
|
describe 'send_file' do
|
||||||
|
|
|
@ -44,7 +44,7 @@ class LiquidTest < Test::Unit::TestCase
|
||||||
mock_app { get('/') { liquid :no_such_template } }
|
mock_app { get('/') { liquid :no_such_template } }
|
||||||
assert_raise(Errno::ENOENT) { get('/') }
|
assert_raise(Errno::ENOENT) { get('/') }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows passing locals" do
|
it "allows passing locals" do
|
||||||
liquid_app {
|
liquid_app {
|
||||||
liquid '{{ value }}', :locals => { :value => 'foo' }
|
liquid '{{ value }}', :locals => { :value => 'foo' }
|
||||||
|
|
|
@ -211,7 +211,7 @@ class MappedErrorTest < Test::Unit::TestCase
|
||||||
assert_equal 500, status
|
assert_equal 500, status
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows a stack of exception_handlers" do
|
it "allows a stack of exception_handlers" do
|
||||||
mock_app do
|
mock_app do
|
||||||
set :raise_errors, false
|
set :raise_errors, false
|
||||||
error(FirstError) { 'First!' }
|
error(FirstError) { 'First!' }
|
||||||
|
@ -223,7 +223,7 @@ class MappedErrorTest < Test::Unit::TestCase
|
||||||
assert_equal 'Second!', body
|
assert_equal 'Second!', body
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows an exception handler to pass control to the next exception handler" do
|
it "allows an exception handler to pass control to the next exception handler" do
|
||||||
mock_app do
|
mock_app do
|
||||||
set :raise_errors, false
|
set :raise_errors, false
|
||||||
error(500, FirstError) { 'First!' }
|
error(500, FirstError) { 'First!' }
|
||||||
|
|
|
@ -55,7 +55,7 @@ class MarkabyTest < Test::Unit::TestCase
|
||||||
assert_equal "<h1>THIS. IS. <em>SPARTA</em></h1>", body
|
assert_equal "<h1>THIS. IS. <em>SPARTA</em></h1>", body
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders inline markaby blocks with file layouts' do
|
it 'renders inline markaby blocks with file layouts' do
|
||||||
markaby_app { markaby(:layout => :layout2) { text "Hello World" } }
|
markaby_app { markaby(:layout => :layout2) { text "Hello World" } }
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
|
assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
|
||||||
|
@ -65,7 +65,7 @@ class MarkabyTest < Test::Unit::TestCase
|
||||||
mock_app { get('/') { markaby :no_such_template } }
|
mock_app { get('/') { markaby :no_such_template } }
|
||||||
assert_raise(Errno::ENOENT) { get('/') }
|
assert_raise(Errno::ENOENT) { get('/') }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows passing locals" do
|
it "allows passing locals" do
|
||||||
markaby_app {
|
markaby_app {
|
||||||
markaby 'text value', :locals => { :value => 'foo' }
|
markaby 'text value', :locals => { :value => 'foo' }
|
||||||
|
|
|
@ -34,7 +34,7 @@ class RablTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal '{"openstruct":{"bar":"baz"}}', body
|
assert_equal '{"openstruct":{"bar":"baz"}}', body
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders with file layouts" do
|
it "renders with file layouts" do
|
||||||
rabl_app {
|
rabl_app {
|
||||||
@foo = OpenStruct.new(:bar => 'baz')
|
@foo = OpenStruct.new(:bar => 'baz')
|
||||||
|
@ -43,14 +43,14 @@ class RablTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal '{"qux":{"openstruct":{"bar":"baz"}}}', body
|
assert_equal '{"qux":{"openstruct":{"bar":"baz"}}}', body
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises error if template not found" do
|
it "raises error if template not found" do
|
||||||
mock_app {
|
mock_app {
|
||||||
get('/') { rabl :no_such_template }
|
get('/') { rabl :no_such_template }
|
||||||
}
|
}
|
||||||
assert_raise(Errno::ENOENT) { get('/') }
|
assert_raise(Errno::ENOENT) { get('/') }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "passes rabl options to the rabl engine" do
|
it "passes rabl options to the rabl engine" do
|
||||||
mock_app do
|
mock_app do
|
||||||
get('/') do
|
get('/') do
|
||||||
|
@ -65,7 +65,7 @@ class RablTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_body '<?xml version="1.0" encoding="UTF-8"?><openstruct><bar>baz</bar></openstruct>'
|
assert_body '<?xml version="1.0" encoding="UTF-8"?><openstruct><bar>baz</bar></openstruct>'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "passes default rabl options to the rabl engine" do
|
it "passes default rabl options to the rabl engine" do
|
||||||
mock_app do
|
mock_app do
|
||||||
set :rabl, :format => 'xml'
|
set :rabl, :format => 'xml'
|
||||||
|
@ -81,7 +81,7 @@ class RablTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_body '<?xml version="1.0" encoding="UTF-8"?><openstruct><bar>baz</bar></openstruct>'
|
assert_body '<?xml version="1.0" encoding="UTF-8"?><openstruct><bar>baz</bar></openstruct>'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
|
|
|
@ -44,7 +44,7 @@ class RadiusTest < Test::Unit::TestCase
|
||||||
mock_app { get('/') { radius :no_such_template } }
|
mock_app { get('/') { radius :no_such_template } }
|
||||||
assert_raise(Errno::ENOENT) { get('/') }
|
assert_raise(Errno::ENOENT) { get('/') }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows passing locals" do
|
it "allows passing locals" do
|
||||||
radius_app {
|
radius_app {
|
||||||
radius '<r:value />', :locals => { :value => 'foo' }
|
radius '<r:value />', :locals => { :value => 'foo' }
|
||||||
|
|
|
@ -47,13 +47,13 @@ class RouteAddedHookTest < Test::Unit::TestCase
|
||||||
assert_equal [["GET", "/"], ["HEAD", "/"]],
|
assert_equal [["GET", "/"], ["HEAD", "/"]],
|
||||||
RouteAddedTest.routes
|
RouteAddedTest.routes
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should pass route blocks as an argument" do
|
it "should pass route blocks as an argument" do
|
||||||
mock_app(Class.new(Sinatra::Base)) do
|
mock_app(Class.new(Sinatra::Base)) do
|
||||||
register RouteAddedTest
|
register RouteAddedTest
|
||||||
get('/') {}
|
get('/') {}
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_kind_of Proc, RouteAddedTest.procs.first
|
assert_kind_of Proc, RouteAddedTest.procs.first
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -75,9 +75,9 @@ class ScssTest < Test::Unit::TestCase
|
||||||
mock_app do
|
mock_app do
|
||||||
set :scss, {:style => :compact} # default scss style is :nested
|
set :scss, {:style => :compact} # default scss style is :nested
|
||||||
get('/') {
|
get('/') {
|
||||||
scss("#scss {\n background-color: white;\n color: black;\n}")
|
scss("#scss {\n background-color: white;\n color: black;\n}")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
get '/'
|
get '/'
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal "#scss { background-color: white; color: black; }\n", body
|
assert_equal "#scss { background-color: white; color: black; }\n", body
|
||||||
|
|
|
@ -5,7 +5,7 @@ class SinatraTest < Test::Unit::TestCase
|
||||||
app = Sinatra.new { get('/') { 'Hello World' } }
|
app = Sinatra.new { get('/') { 'Hello World' } }
|
||||||
assert_same Sinatra::Base, app.superclass
|
assert_same Sinatra::Base, app.superclass
|
||||||
end
|
end
|
||||||
|
|
||||||
it "responds to #template_cache" do
|
it "responds to #template_cache" do
|
||||||
assert_kind_of Tilt::Cache, Sinatra::Base.new!.template_cache
|
assert_kind_of Tilt::Cache, Sinatra::Base.new!.template_cache
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,13 +17,13 @@ class SlimTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal "<h1>Hiya</h1>", body
|
assert_equal "<h1>Hiya</h1>", body
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders .slim files in views path' do
|
it 'renders .slim files in views path' do
|
||||||
slim_app { slim :hello }
|
slim_app { slim :hello }
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal "<h1>Hello From Slim</h1>", body
|
assert_equal "<h1>Hello From Slim</h1>", body
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders with inline layouts" do
|
it "renders with inline layouts" do
|
||||||
mock_app do
|
mock_app do
|
||||||
layout { %(h1\n | THIS. IS. \n == yield.upcase ) }
|
layout { %(h1\n | THIS. IS. \n == yield.upcase ) }
|
||||||
|
@ -33,27 +33,27 @@ class SlimTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>", body
|
assert_equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>", body
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders with file layouts" do
|
it "renders with file layouts" do
|
||||||
slim_app { slim('| Hello World', :layout => :layout2) }
|
slim_app { slim('| Hello World', :layout => :layout2) }
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal "<h1>Slim Layout!</h1><p>Hello World</p>", body
|
assert_equal "<h1>Slim Layout!</h1><p>Hello World</p>", body
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises error if template not found" do
|
it "raises error if template not found" do
|
||||||
mock_app { get('/') { slim(:no_such_template) } }
|
mock_app { get('/') { slim(:no_such_template) } }
|
||||||
assert_raise(Errno::ENOENT) { get('/') }
|
assert_raise(Errno::ENOENT) { get('/') }
|
||||||
end
|
end
|
||||||
|
|
||||||
HTML4_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
|
HTML4_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
|
||||||
|
|
||||||
it "passes slim options to the slim engine" do
|
it "passes slim options to the slim engine" do
|
||||||
mock_app { get('/') { slim("x foo='bar'", :attr_wrapper => "'") }}
|
mock_app { get('/') { slim("x foo='bar'", :attr_wrapper => "'") }}
|
||||||
get '/'
|
get '/'
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_body "<x foo='bar'></x>"
|
assert_body "<x foo='bar'></x>"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "passes default slim options to the slim engine" do
|
it "passes default slim options to the slim engine" do
|
||||||
mock_app do
|
mock_app do
|
||||||
set :slim, :attr_wrapper => "'"
|
set :slim, :attr_wrapper => "'"
|
||||||
|
@ -63,7 +63,7 @@ class SlimTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_body "<x foo='bar'></x>"
|
assert_body "<x foo='bar'></x>"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "merges the default slim options with the overrides and passes them to the slim engine" do
|
it "merges the default slim options with the overrides and passes them to the slim engine" do
|
||||||
mock_app do
|
mock_app do
|
||||||
set :slim, :attr_wrapper => "'"
|
set :slim, :attr_wrapper => "'"
|
||||||
|
|
|
@ -288,7 +288,7 @@ __END__
|
||||||
@@ foo
|
@@ foo
|
||||||
this is foo
|
this is foo
|
||||||
|
|
||||||
@@ bar
|
@@ bar
|
||||||
There's a space after 'bar'!
|
There's a space after 'bar'!
|
||||||
|
|
||||||
@@ foo bar
|
@@ foo bar
|
||||||
|
|
|
@ -50,7 +50,7 @@ class YajlTest < Test::Unit::TestCase
|
||||||
it 'decorates the json with a callback' do
|
it 'decorates the json with a callback' do
|
||||||
yajl_app do
|
yajl_app do
|
||||||
yajl(
|
yajl(
|
||||||
'json = { :foo => "bar" }',
|
'json = { :foo => "bar" }',
|
||||||
{ :callback => 'baz' }
|
{ :callback => 'baz' }
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue