scorched 0.15 → 0.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 252309e125591f6ffd81a1ac36bb79c851aabce8
4
- data.tar.gz: 4100f0dc1f942fb4067f32e27f966b8fb327c8d8
3
+ metadata.gz: 4f2b6b091aaaea15a4bd11fbcc7d70fc27e783d1
4
+ data.tar.gz: db2e3b73d7b0f2aa82472f90299915cdfa3e2c4a
5
5
  SHA512:
6
- metadata.gz: 5cda7022f16ff4d70a47552dbb6563f86e8ece672036b221373a639990c48bd12fbedce6e7989eabe0cf9282a08621eec342a129ea9c74dadd66b0b289642b25
7
- data.tar.gz: 6dc0e3f1aef90a462a610f33fc7ffc34f087f5426f7919c2ae555f3599aeb048668fb7c72e3e7e39b6ea4664eeb68048b060b255af6ae2687f9c7d578e5678ff
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. The consequences of this have made 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 traditional instance methods. The decision to allow developers to implement helpers and other common functionality as proper methods not only makes Controllers somewhat more predictable and familiar, but also allows for such helpers to be inheritable via plain-old class inheritance.
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
- Perhaps another design oversight of other frameworks has been 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.
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's 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 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.
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 scorched in an evening.
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, is that unlike other lightweight web frameworks that attempt to hide Rack in the background, Scorched makes no such attempts, 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.
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 a good reason.
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 invoke a false sense of security
13
- * Filter priorities - They're technically possible, but I believe it would introduce the potential for _filter hell_; badly written filters and mass confusion. 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.
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 `patch`. These methods automatically define the corresponding `:method` condition, with the `get` helper also including `head` as an accepted HTTP method.
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, like `set_cookie` and `delete_cookie` can take directly. Deleting still works when a Hash is provided, as long as the `value` property is nil.
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 conveniance, a `session` helper is provided. This merely acts as an alias to `request['rack.session']` however. It was raise an exception if called without any Rack session middleware loaded, such as `Rack::Session::Cookie`.
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, and especially web applications, is to provide a message on the next page load corresponding to an action that a user 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
+ ###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. Because of this, views have been implemented as a single method, `render`.
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, were as a string is assumed to be the template markup. `render` can also takes a set of options.
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. A common example being the `:locals` option, used to set local variables made available within the scope of the view.
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. Layout's use this feature.
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 a 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.
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.
@@ -12,6 +12,6 @@ before user_agent: /MSIE|Windows/ do
12
12
  end
13
13
 
14
14
  get '/' do
15
- "Welcome to #{env['myapp.settings.site_name']}!"
15
+ "Welcome #{env['myapp.user.name']}!"
16
16
  end
17
17
  ```
@@ -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.
@@ -0,0 +1,9 @@
1
+ require File.expand_path('../../lib/scorched.rb', __FILE__)
2
+
3
+ class App < Scorched::Controller
4
+ get '/' do
5
+ 'hello world'
6
+ end
7
+ end
8
+
9
+ run App
@@ -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 |env|
170
- env['scorched.response'].body = instance_exec(*env['scorched.request'].captures, &block)
171
- env['scorched.response']
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.request'] ||= Request.new(env)
243
- env['scorched.response'] ||= Response.new
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! (Proc === target) ? instance_exec(env, &target) : target.call(env)
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['SCRIPT_NAME']
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
- [request.script_name, path].join('/').gsub(%r{/+}, '/')
484
+ [env['scorched.root_path'], path].join('/').gsub(%r{/+}, '/')
481
485
  else
482
- request.script_name
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
@@ -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.partition(matched_path).last
29
- path[0,0] = '/' if path.empty? || matched_path[-1] == '/'
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
@@ -1,3 +1,3 @@
1
1
  module Scorched
2
- VERSION = '0.15'
2
+ VERSION = '0.16'
3
3
  end
@@ -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').body.should == "ok"
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
- response.body << 'hello'
620
+ effects.push 1
621
+ response.body << 'x'
595
622
  pass
596
623
  end
597
624
  end
598
- app.get('/sub') { response.body << ' there' }
599
- rt.get('/sub').body.should == 'hello there'
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.15'
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-07-05 00:00:00.000000000 Z
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/test.ru
126
+ - examples/simple.ru
127
127
  - lib/scorched.rb
128
128
  - lib/scorched/collection.rb
129
129
  - lib/scorched/controller.rb
@@ -1,10 +0,0 @@
1
- require File.expand_path('../../lib/scorched.rb', __FILE__)
2
-
3
- class MyApp < Scorched::Controller
4
- get '/*' do |part|
5
- p part
6
- part
7
- end
8
- end
9
-
10
- run MyApp