scorched 0.15 → 0.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +5 -0
- data/README.md +6 -6
- data/TODO.md +3 -7
- data/docs/02_fundamentals/02_configuration.md +3 -3
- data/docs/02_fundamentals/03_routing.md +1 -1
- data/docs/02_fundamentals/07_request_and_session_data.md +7 -5
- data/docs/02_fundamentals/08_views.md +7 -5
- data/docs/02_fundamentals/09_sharing_request_state.md +1 -1
- data/docs/03_further_reading/running_unit_tests.md +1 -1
- data/examples/simple.ru +9 -0
- data/lib/scorched/controller.rb +26 -22
- data/lib/scorched/request.rb +3 -3
- data/lib/scorched/version.rb +1 -1
- data/spec/controller_spec.rb +53 -8
- metadata +3 -3
- data/examples/test.ru +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f2b6b091aaaea15a4bd11fbcc7d70fc27e783d1
|
4
|
+
data.tar.gz: db2e3b73d7b0f2aa82472f90299915cdfa3e2c4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e937339dd3d1470e201050a395d68f4cf3635c355683c5fee6a4570cc12044e7f584dd57bed84fb01c89ac3cc89ac73f026a1b88cd9dc06dd08fdd79bdf748d7
|
7
|
+
data.tar.gz: 3fb1e340771264fe6738d6ea030e0387cea91fc716fa6b651883194973b12b498dd7b0bee27a6994d64ea126a936c47da057fc45f8f6698793fad553685c58b5
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
### v0.16
|
5
|
+
* A copy of the Rack env hash is now handed off to sub-controllers and other Rack-callable objects, with `PATH_INFO` and `SCRIPT_NAME` now set to appropriate values, bring Scorched inline with the Rack specification. This differs from the original behaviour which was to just forward on the original env hash unmodified.
|
6
|
+
* URL helper method `absolute` and `url` now use the new env property `scorched.root_path` as their base path, rather than `SCRIPT_NAME`.
|
7
|
+
* Helpers for HTTP methods `link` and `unlink` have been added.
|
8
|
+
|
4
9
|
### v0.15
|
5
10
|
* Route DSL methods (`route`, `get`, `post`, ...) now accept an array of patterns as the pattern argument. Each pattern is defined as a separate mapping, sharing the same target proc. This provides a cleaner and more efficient solution to simply wrapping a route definition within a loop.
|
6
11
|
* URI unescaping has been implemented for `Scorched::Request#unmatched_path`. This modification directly affects route matching. Previously, routes were matched against the escaped path, e.g. `/this%20has%20spaces`. Routes are now matched against the unescaped form `/this has spaces`. The only exception is the escaped forward-slash `%2F` and percent sign `%25` which remain unaltered for the fact their unescaped form as special meaning which you wouldn't be able to disambiguate. It's however safe to unescape the path a second time to resolve these characters.
|
data/README.md
CHANGED
@@ -39,23 +39,23 @@ Scorched requires Ruby 2.0 or above. If you've got Ruby 2.0.0-p195 and newer, yo
|
|
39
39
|
|
40
40
|
The Errors of Our Past (and Present!)
|
41
41
|
----------------------
|
42
|
-
One of the mistakes made by a lot of other Ruby frameworks is to not leverage the power of the class.
|
42
|
+
One of the mistakes made by a lot of other Ruby frameworks is to not leverage the power of the class. Consequentially, this makes for some awkwardness. Helpers, for example, are a classical reinvention of what classes and modules are already made to solve. Scorched implements Controllers as classes, which, in addition to having their own DSL, allow you to define and call whatever you need as standard instance methods. The decision to allow developers to implement helpers and other common functionality as standard instance methods not only makes Controllers somewhat more predictable and familiar, but also allows for such helpers to be inheritable via plain old class inheritance.
|
43
43
|
|
44
|
-
|
44
|
+
Another design oversight of other frameworks is the lack of consideration for the hierarchical nature of websites and the fact that sub-directories are often expected to inherit attributes of their parents. Scorched supports sub-controllers to any arbitrary depth, with each controller's configuration, filters, route conditions, etc. applied along the way. This can help in many areas of web development, including security, restful interfaces, and interchangeable content types.
|
45
45
|
|
46
46
|
|
47
47
|
Design Philosophy
|
48
48
|
-----------------
|
49
|
-
Scorched has a relatively simple design philosophy. The main objective is to keep Scorched lean and generic. Scorched refrains from expressing any opinion about how you design and structure your application. The general idea is to give developers the constructs to quickly put together small, medium and even large websites and applications.
|
49
|
+
Scorched has a relatively simple design philosophy. The main objective is to keep Scorched lean and generic. Scorched refrains from expressing any opinion about how you should design and structure your application. The general idea is to give developers the constructs to quickly put together small, medium and even large websites and applications.
|
50
50
|
|
51
|
-
There
|
51
|
+
There is little need for a framework to be opinionated if the opinions of the developer can be quickly and easily built into it on a per-application basis. To do this effectively, developers will really need to understand Scorched, and the best way to facilitate that is to lower the learning curve, by keeping the core design logical, predictable and concise.
|
52
52
|
|
53
53
|
|
54
54
|
Magicians Not Welcome
|
55
55
|
---------------------
|
56
|
-
Scorched aims to be raw and transparent. Magic has no place. A thoughtful and simple design means there's no requirement for magic. Because of that, most developers should be able to master
|
56
|
+
Scorched aims to be raw and transparent. Magic has no place. A thoughtful and simple design means there's no requirement for magic. Because of that, most developers should be able to master Scorched in an evening.
|
57
57
|
|
58
|
-
Part of what keeps Scorched lightweight
|
58
|
+
Part of what keeps Scorched lightweight is that unlike other lightweight web frameworks that attempt to hide Rack in the background, Scorched makes no such attempt, very rarely providing functionality that overlaps with what's already provided by Rack. In fact, familiarity with Rack is somewhat of a pre-requisite to mastering Scorched.
|
59
59
|
|
60
60
|
|
61
61
|
First Impressions
|
data/TODO.md
CHANGED
@@ -1,17 +1,13 @@
|
|
1
1
|
To Do
|
2
2
|
=====
|
3
|
-
* If one or more matches are found, but their conditions don't pass, a 403 should be returned instead of a 404.
|
4
3
|
* Make specs for Collection and Options classes more thorough, e.g. test all non-reading modifiers such as clear, delete, etc.
|
5
4
|
|
6
5
|
|
7
6
|
Unlikely
|
8
7
|
========
|
9
|
-
These features are unlikely to be implemented unless someone provides
|
8
|
+
These features are unlikely to be implemented unless someone provides good enough justification.
|
10
9
|
|
11
10
|
* Mutex locking option - I'm of the opinion that the web server should be configured for the concurrency model of the application, rather than the framework.
|
12
|
-
* Using Rack::Protection by default - The problem here is that a good portion of Rack::Protection involves sessions, and given that Scorched doesn't itself load any session middleware, these components of Rack::Protection would have to be excluded. I wouldn't want to
|
13
|
-
* Filter priorities - They're technically possible, but I believe it would introduce the potential for _filter hell_; badly written filters and mass
|
11
|
+
* Using Rack::Protection by default - The problem here is that a good portion of Rack::Protection involves sessions, and given that Scorched doesn't itself load any session middleware, these components of Rack::Protection would have to be excluded. I wouldn't want to lull anyone into a false sense of security
|
12
|
+
* Filter priorities - They're technically possible, but I believe it would introduce the potential for _filter hell_; badly written filters and mass hysteria. Filter order has to be logical and predictable. Adding prioritisation would undermine that, and make for lazy use of filters. By not having prioritisation, there's incentive to design filters to be order-agnostic.
|
14
13
|
* Verbose logging - I originally intended to add some form of debug-style logging to show the complete flow of a request as it traverses through filters and controllers, etc. For a couple of reasons, I've decided to leave this out of Scorched. For those unfamiliar with the order in which filters and routes are invoked, it's better to learn through first-hand experience writing little test applications, rather than depending on debug logging.
|
15
|
-
|
16
|
-
|
17
|
-
More things will be added as they're thought of and considered.
|
@@ -19,9 +19,9 @@ Each configuration is listed below, with the default value of each included. Not
|
|
19
19
|
The directory Scorched should serve static files from. Should be set to false if the web server or some other middleware is serving static files.
|
20
20
|
* `config[:strip_trailing_slash] = :redirect`
|
21
21
|
Controls how trailing forward slashes in requests are handled.
|
22
|
-
* `:redirect` - Strips and redirects URL's ending in a forward slash
|
23
|
-
* `:ignore` - Internally ignores trailing slash
|
24
|
-
* `false` - Does nothing. Respects the presence of a trailing forward flash.
|
22
|
+
* `:redirect` - Strips and redirects URL's ending in a forward slash. Note that for efficiency sake, the redirection takes place in the first controller that has this option set to `:redirect`, hence a sub-controller that otherwise matches the request will never be invoked, even if it sets `:strip_trailing_slash` to something other than `:redirect`.
|
23
|
+
* `:ignore` - Internally ignores (pretends it doesn't exist) any trailing slash
|
24
|
+
* `false` - Does nothing. Respects the presence of a trailing forward flash, as it would any other trailing character.
|
25
25
|
|
26
26
|
You can also configure the default options when rendering views by setting them on the `render_defaults` hash. The options specified here are merged with those provided when calling the `render` method, with the explicit options obviously taking precedence over the defaults.
|
27
27
|
|
@@ -37,7 +37,7 @@ The first exception is that the pattern must match to the end of the request pat
|
|
37
37
|
|
38
38
|
The other more notable exception is in how the given block is treated. The block given to the route helper is wrapped in another proc. The wrapping proc does a couple of things. It first sends all the captures in the url pattern as arguments to the given block; this is shown in the example above. The other thing it does is takes care of assigning the return value to the body of the response.
|
39
39
|
|
40
|
-
In the latter of the two examples above, a `:method` condition defines what methods the route is intended to process. The first example has no such condition, so it accepts all HTTP methods. Typically however, a route will handle a single HTTP method, which is why Scorched also provides the convenience helpers: `get`, `post`, `put`, `delete`, `head`, `options`, and `
|
40
|
+
In the latter of the two examples above, a `:method` condition defines what methods the route is intended to process. The first example has no such condition, so it accepts all HTTP methods. Typically however, a route will handle a single HTTP method, which is why Scorched also provides the convenience helpers: `get`, `post`, `put`, `delete`, `head`, `options`, `patch`, `link` and `unlink`. These methods automatically define the corresponding `:method` condition, with the `get` helper also including `head` as an accepted HTTP method.
|
41
41
|
|
42
42
|
Pattern Matching
|
43
43
|
----------------
|
@@ -14,6 +14,8 @@ post '/' do
|
|
14
14
|
end
|
15
15
|
```
|
16
16
|
|
17
|
+
One of the few opinions Scorched does maintain (albeit without imposition), is that GET and POST data should be accessed by their respective methods. GET and POST data are semantically different, so if you're not concerned about where the data came from, it may be a good sign you're doing something wrong.
|
18
|
+
|
17
19
|
Uploaded files are also accessible as ordinary fields, except the associated value is a hash of properties, instead of a string. An example of an application that accepts file uploads is included in the "examples" directory of the Scorched git repository.
|
18
20
|
|
19
21
|
Cookies
|
@@ -28,7 +30,7 @@ def '/' do
|
|
28
30
|
end
|
29
31
|
```
|
30
32
|
|
31
|
-
For each of the above lines, the corresponding Rack methods are called, e.g. `Rack::Requeste#cookies`, `Rack::Response#set_cookie` and `Rack::Response#delete_cookie`. The values for setting and deleting a cookie can also be a hash,
|
33
|
+
For each of the above lines, the corresponding Rack methods are called, e.g. `Rack::Requeste#cookies`, `Rack::Response#set_cookie` and `Rack::Response#delete_cookie`. The values for setting and deleting a cookie can also be a hash, as per the documentation for `set_cookie` and `delete_cookie`. Deletion is still possible when a Hash is provided, as long as the `value` property is nil.
|
32
34
|
|
33
35
|
```ruby
|
34
36
|
def '/' do
|
@@ -40,7 +42,7 @@ end
|
|
40
42
|
|
41
43
|
Sessions
|
42
44
|
--------
|
43
|
-
Sessions are completely handled by Rack. For
|
45
|
+
Sessions are completely handled by Rack. For convenience, Scorched provides a `session` helper. This merely acts as an alias to `request['rack.session']`. It will raise an exception if called without any Rack session middleware loaded, such as `Rack::Session::Cookie`.
|
44
46
|
|
45
47
|
```ruby
|
46
48
|
class App < Scorched::Controller
|
@@ -54,10 +56,10 @@ class App < Scorched::Controller
|
|
54
56
|
end
|
55
57
|
```
|
56
58
|
|
57
|
-
###Flash
|
58
|
-
A common requirement for websites,
|
59
|
+
###Flash Session Data
|
60
|
+
A common requirement for websites, especially web applications, is to provide a message on the next page load corresponding to an action that a user has just performed. A common framework idiom that Scorched happily implements are flash session variables - special session data that lives for only a single page load.
|
59
61
|
|
60
|
-
This isn't as trivial to implement as it may sound at a glance, which is why Scorched provides this helper.
|
62
|
+
This isn't as trivial to implement as it may sound at a glance, which is why Scorched provides this helper out-of-the-box.
|
61
63
|
|
62
64
|
```ruby
|
63
65
|
get '/' do
|
@@ -1,17 +1,19 @@
|
|
1
1
|
Views
|
2
2
|
=====
|
3
3
|
|
4
|
-
Scorched uses Tilt to render templates in various supported formats.
|
4
|
+
Scorched uses Tilt to render templates in various supported formats. Thanks of this abstraction, views have been implemented as a single method `render`.
|
5
5
|
|
6
|
-
`render` can take a file path or a string as the template. If a symbol is given, it assumes it's a file path,
|
6
|
+
`render` can take a file path or a string as the template. If a symbol is given, it assumes it's a file path, where as a string is assumed to be the template markup. `render` can also take a set of options. These options get their defaults from the `render_defaults` hash, inherited by each sub-controller.
|
7
7
|
|
8
8
|
* `:dir` - The directory containing the views. This can be absolute or relative to the current working directory.
|
9
9
|
* `:layout` - The template to render _around_ the view.
|
10
10
|
* `:engine` - The template engine to use if it can't be derived from the file name. This is always required for string templates. Can be any string or symbol that Tilt recognises, e.g :erb, :haml, :sass, etc.
|
11
|
+
* `:locals` - Hash of local variables to be made available in the context of the view.
|
12
|
+
* `:tilt` - Options to be passed directly to Tilt. Required to avoid conflicts between Scorched options and the options of some renderers.
|
11
13
|
|
12
|
-
Any unrecognised options are passed through to Tilt and the corresponding rendering engine.
|
14
|
+
Any unrecognised options are passed through to Tilt and the corresponding rendering engine. Where such options conflict with those used by Scorched (dependant on the rendering engine), the `:tilt` option provides an unambiguous means to directly pass through those options.
|
13
15
|
|
14
|
-
Finally, `render` takes an optional block to be _yielded_ within the view being rendered, if supported by the rendering engine.
|
16
|
+
Finally, `render` takes an optional block to be _yielded_ within the view being rendered, if supported by the rendering engine. This feature is used internally as part of the implementation of layouts.
|
15
17
|
|
16
18
|
Layouts
|
17
19
|
-------
|
@@ -19,4 +21,4 @@ When a layout is given, a subsequent call to `render` is made, with the rendered
|
|
19
21
|
|
20
22
|
Partials
|
21
23
|
--------
|
22
|
-
There are cases where
|
24
|
+
There are cases where you may want a view to be composed of more than just a layout and a single view. The view may contain one or more sub-views, commonly referred to as partials. Scorched makes provisions for this by ignoring the default layout when `render` is called within a view, hence negating the requirement to explicitly override the layout.
|
@@ -3,4 +3,4 @@ Running Unit Tests
|
|
3
3
|
|
4
4
|
If doing any development on Scorched, such as if you want to fork it or contribute patches to it, you will probably want to run the suite of tests that accompany it. The few dependancies required for running the Scorched unit tests are installed either when you install the Scorched gem, or by running `bundle` in the root of the Scorched source tree.
|
5
5
|
|
6
|
-
All unit tests have been written using RSpec. To run the tests, `cd` into the root of the Scorched source tree from a terminal, and run `rspec`.
|
6
|
+
All unit tests have been written using RSpec. To run the tests, `cd` into the root of the Scorched source tree from a terminal, and run `rspec`. Alternatively, you can run `rake spec` which will achieve the same result.
|
data/examples/simple.ru
ADDED
data/lib/scorched/controller.rb
CHANGED
@@ -9,6 +9,8 @@ module Scorched
|
|
9
9
|
include Scorched::Collection('before_filters')
|
10
10
|
include Scorched::Collection('after_filters', true)
|
11
11
|
include Scorched::Collection('error_filters')
|
12
|
+
|
13
|
+
attr_reader :request, :response
|
12
14
|
|
13
15
|
config << {
|
14
16
|
:auto_pass => false, # Automatically _pass_ request back to outer controller if no route matches.
|
@@ -166,9 +168,9 @@ module Scorched
|
|
166
168
|
# options(pattern = nil, priority = nil, **conds, &block)
|
167
169
|
# patch(pattern = nil, priority = nil, **conds, &block)
|
168
170
|
def route(pattern = nil, priority = nil, **conds, &block)
|
169
|
-
target = lambda do
|
170
|
-
|
171
|
-
|
171
|
+
target = lambda do
|
172
|
+
response.body = instance_exec(*request.captures, &block)
|
173
|
+
response
|
172
174
|
end
|
173
175
|
[*pattern].compact.each do |pattern|
|
174
176
|
self << {pattern: compile(pattern, true), priority: priority, conditions: conds, target: target}
|
@@ -176,7 +178,7 @@ module Scorched
|
|
176
178
|
target
|
177
179
|
end
|
178
180
|
|
179
|
-
['get', 'post', 'put', 'delete', 'head', 'options', 'patch'].each do |method|
|
181
|
+
['get', 'post', 'put', 'delete', 'head', 'options', 'patch', 'link', 'unlink'].each do |method|
|
180
182
|
methods = (method == 'get') ? ['GET', 'HEAD'] : [method.upcase]
|
181
183
|
define_method(method) do |*args, **conds, &block|
|
182
184
|
conds.merge!(method: methods)
|
@@ -239,8 +241,11 @@ module Scorched
|
|
239
241
|
define_singleton_method :env do
|
240
242
|
env
|
241
243
|
end
|
242
|
-
env['scorched.
|
243
|
-
env['scorched.
|
244
|
+
env['scorched.root_path'] ||= env['SCRIPT_NAME']
|
245
|
+
env['scorched.path_info'] ||= env['PATH_INFO']
|
246
|
+
env['scorched.script_name'] ||= env['SCRIPT_NAME']
|
247
|
+
@request = Request.new(env)
|
248
|
+
@response = Response.new
|
244
249
|
end
|
245
250
|
|
246
251
|
def action
|
@@ -266,7 +271,16 @@ module Scorched
|
|
266
271
|
request.breadcrumb << match
|
267
272
|
break if catch(:pass) {
|
268
273
|
target = match.mapping[:target]
|
269
|
-
response.merge!
|
274
|
+
response.merge! begin
|
275
|
+
if Proc === target
|
276
|
+
instance_exec(&target)
|
277
|
+
else
|
278
|
+
target.call(env.merge(
|
279
|
+
'SCRIPT_NAME' => request.matched_path,
|
280
|
+
'PATH_INFO' => request.unmatched_path[match.path.length..-1]
|
281
|
+
))
|
282
|
+
end
|
283
|
+
end
|
270
284
|
@_handled = true
|
271
285
|
}
|
272
286
|
request.breadcrumb.pop
|
@@ -347,16 +361,6 @@ module Scorched
|
|
347
361
|
throw :pass
|
348
362
|
end
|
349
363
|
|
350
|
-
# Convenience method for accessing Rack request.
|
351
|
-
def request
|
352
|
-
env['scorched.request']
|
353
|
-
end
|
354
|
-
|
355
|
-
# Convenience method for accessing Rack response.
|
356
|
-
def response
|
357
|
-
env['scorched.response']
|
358
|
-
end
|
359
|
-
|
360
364
|
# Convenience method for accessing Rack session.
|
361
365
|
def session
|
362
366
|
env['rack.session']
|
@@ -453,7 +457,7 @@ module Scorched
|
|
453
457
|
output
|
454
458
|
end
|
455
459
|
end
|
456
|
-
|
460
|
+
|
457
461
|
# Takes an optional URL, relative to the applications root, and returns a fully qualified URL.
|
458
462
|
# Example: url('/example?show=30') #=> https://localhost:9292/myapp/example?show=30
|
459
463
|
def url(path = nil)
|
@@ -462,7 +466,7 @@ module Scorched
|
|
462
466
|
scheme: env['rack.url_scheme'],
|
463
467
|
host: env['SERVER_NAME'],
|
464
468
|
port: env['SERVER_PORT'].to_i,
|
465
|
-
path: env['
|
469
|
+
path: env['scorched.root_path'],
|
466
470
|
)
|
467
471
|
if path
|
468
472
|
path[0,0] = '/' unless path[0] == '/'
|
@@ -477,9 +481,9 @@ module Scorched
|
|
477
481
|
def absolute(path = nil)
|
478
482
|
return path if path && URI.parse(path).scheme
|
479
483
|
return_path = if path
|
480
|
-
[
|
484
|
+
[env['scorched.root_path'], path].join('/').gsub(%r{/+}, '/')
|
481
485
|
else
|
482
|
-
|
486
|
+
env['scorched.root_path']
|
483
487
|
end
|
484
488
|
return_path[0] == '/' ? return_path : return_path.insert(0, '/')
|
485
489
|
end
|
@@ -533,4 +537,4 @@ module Scorched
|
|
533
537
|
config[:logger].add(type, message)
|
534
538
|
end
|
535
539
|
end
|
536
|
-
end
|
540
|
+
end
|
data/lib/scorched/request.rb
CHANGED
@@ -25,8 +25,8 @@ module Scorched
|
|
25
25
|
|
26
26
|
# The remaining portion of the path that has yet to be matched by any mappings.
|
27
27
|
def unmatched_path
|
28
|
-
path = unescaped_path.
|
29
|
-
path[0,0] = '/' if path
|
28
|
+
path = unescaped_path.dup
|
29
|
+
path[0,0] = '/' if (path[0] != '/' && matched_path[-1] == '/') || path.empty?
|
30
30
|
path
|
31
31
|
end
|
32
32
|
|
@@ -42,4 +42,4 @@ module Scorched
|
|
42
42
|
paths.join('/').gsub(%r{/+}, '/')
|
43
43
|
end
|
44
44
|
end
|
45
|
-
end
|
45
|
+
end
|
data/lib/scorched/version.rb
CHANGED
data/spec/controller_spec.rb
CHANGED
@@ -87,7 +87,9 @@ module Scorched
|
|
87
87
|
app << {pattern: '/ab', target: Class.new(Scorched::Controller) do
|
88
88
|
map(pattern: 'out', target: gh)
|
89
89
|
end}
|
90
|
-
rt.get('/about')
|
90
|
+
resp = rt.get('/about')
|
91
|
+
resp.status.should == 200
|
92
|
+
resp.body.should == "ok"
|
91
93
|
end
|
92
94
|
|
93
95
|
it "unmatched path begins with forward slash if last match was up to or included a forward slash" do
|
@@ -264,7 +266,27 @@ module Scorched
|
|
264
266
|
end}
|
265
267
|
rt.get('/article/hello-world').body.should == 'hello-world'
|
266
268
|
end
|
267
|
-
|
269
|
+
|
270
|
+
they "have access to original unmangled PATH_INFO via 'scorched.path_info'" do
|
271
|
+
app << {pattern: '/article', target: Class.new(Scorched::Controller) do
|
272
|
+
get('/name') {
|
273
|
+
env['scorched.path_info']
|
274
|
+
}
|
275
|
+
end}
|
276
|
+
rt.get('/article/name').body.should == '/article/name'
|
277
|
+
end
|
278
|
+
|
279
|
+
it "propagates correclty mangles escaped PATH_INFO before passing to sub-controller" do
|
280
|
+
app << {pattern: '/:category', target: Class.new(Scorched::Controller) do
|
281
|
+
get('/:name') {
|
282
|
+
'hello'
|
283
|
+
}
|
284
|
+
end}
|
285
|
+
resp = rt.get('/big%20articles/article%20name')
|
286
|
+
resp.status.should == 200
|
287
|
+
resp.body.should == 'hello'
|
288
|
+
end
|
289
|
+
|
268
290
|
describe "controller helper" do
|
269
291
|
it "can be given no arguments" do
|
270
292
|
app.controller do
|
@@ -411,6 +433,10 @@ module Scorched
|
|
411
433
|
example "inherited filters which fail to satisfy their conditions are re-evaluated at every level" do
|
412
434
|
order = []
|
413
435
|
sub_class = app.controller do
|
436
|
+
def initialize(env)
|
437
|
+
super(env)
|
438
|
+
response.status = 500
|
439
|
+
end
|
414
440
|
before { order << :third }
|
415
441
|
get('/hello') { }
|
416
442
|
end
|
@@ -420,7 +446,6 @@ module Scorched
|
|
420
446
|
end
|
421
447
|
app.before do
|
422
448
|
order << :first
|
423
|
-
response.status = 500
|
424
449
|
end
|
425
450
|
rt.get('/hello')
|
426
451
|
order.should == %i{first second third}
|
@@ -588,15 +613,21 @@ module Scorched
|
|
588
613
|
end
|
589
614
|
|
590
615
|
it "invokes the next match in parent controller if passed from filter" do
|
616
|
+
effects = []
|
591
617
|
app.controller '/sub' do
|
592
618
|
get('/') { }
|
593
619
|
after do
|
594
|
-
|
620
|
+
effects.push 1
|
621
|
+
response.body << 'x'
|
595
622
|
pass
|
596
623
|
end
|
597
624
|
end
|
598
|
-
app.get('/sub') {
|
599
|
-
|
625
|
+
app.get('/sub') {
|
626
|
+
effects.push 2
|
627
|
+
response.body << 'y'
|
628
|
+
}
|
629
|
+
rt.get('/sub').body.should == 'y'
|
630
|
+
effects.should == [1, 2]
|
600
631
|
end
|
601
632
|
|
602
633
|
it "results in uncaught symbol if passing within filter of root controller " do
|
@@ -974,7 +1005,7 @@ module Scorched
|
|
974
1005
|
let(:root_app) do
|
975
1006
|
Class.new(Scorched::Controller)
|
976
1007
|
end
|
977
|
-
|
1008
|
+
|
978
1009
|
let(:app) do
|
979
1010
|
this = self
|
980
1011
|
builder = Rack::Builder.new
|
@@ -1001,6 +1032,13 @@ module Scorched
|
|
1001
1032
|
my_app.get('/') { url(test_url) }
|
1002
1033
|
rt.get('/myapp').body.should == test_url
|
1003
1034
|
end
|
1035
|
+
|
1036
|
+
it "generates URL from inside subcontroller defined with controller helper" do
|
1037
|
+
root_app.controller '/sub2' do
|
1038
|
+
get('/') { url('hi') }
|
1039
|
+
end
|
1040
|
+
rt.get('https://scorchedrb.com:73/sub2').body.should == 'https://scorchedrb.com:73/hi'
|
1041
|
+
end
|
1004
1042
|
end
|
1005
1043
|
|
1006
1044
|
describe "absolute" do
|
@@ -1024,8 +1062,15 @@ module Scorched
|
|
1024
1062
|
my_app.get('/') { absolute(test_url) }
|
1025
1063
|
rt.get('/myapp').body.should == test_url
|
1026
1064
|
end
|
1065
|
+
|
1066
|
+
it "returns an absolute URL path for subcontroller defined with controller helper" do
|
1067
|
+
root_app.controller '/sub2' do
|
1068
|
+
get('/') { absolute }
|
1069
|
+
end
|
1070
|
+
rt.get('https://scorchedrb.com:73/sub2').body.should == '/'
|
1071
|
+
end
|
1027
1072
|
end
|
1028
1073
|
end
|
1029
1074
|
|
1030
1075
|
end
|
1031
|
-
end
|
1076
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scorched
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.16'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Wardrop
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -123,7 +123,7 @@ files:
|
|
123
123
|
- docs/03_further_reading/running_unit_tests.md
|
124
124
|
- examples/file_upload.ru
|
125
125
|
- examples/media_types.ru
|
126
|
-
- examples/
|
126
|
+
- examples/simple.ru
|
127
127
|
- lib/scorched.rb
|
128
128
|
- lib/scorched/collection.rb
|
129
129
|
- lib/scorched/controller.rb
|