scorched 0.24 → 0.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +4 -0
- data/README.md +6 -6
- data/TODO.md +7 -0
- data/docs/02_fundamentals/03_routing.md +25 -3
- data/lib/scorched/controller.rb +18 -3
- data/lib/scorched/version.rb +1 -1
- data/spec/controller_spec.rb +16 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10528e9accf1667188d5687163e6badbdab8ef5f
|
4
|
+
data.tar.gz: abfacc42fe2b69ffcf1152ca256cc31a4ec0130e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7a1e567e38bad8f7d08da253e4a396febbc9c9b5798120364ac55f8019870fb705d7d24d3042bdb5c9e1b777135f0f47e4c87bf25a3fa1a4942f3588041f02d
|
7
|
+
data.tar.gz: ad78af5c05b6a89e3721c100f87320a6f21ad02f6c7bfe1bbe6f794dad9a0c87f6788beccf849ae649148776f480093d742601222646c11c7fbe2d74b904f386
|
data/CHANGES.md
CHANGED
@@ -3,6 +3,10 @@ Changelog
|
|
3
3
|
|
4
4
|
_Note that Scorched is yet to reach a v1.0 release. This means breaking changes may still be made. If upgrading the version of Scorched for your project, review this changelog carefully._
|
5
5
|
|
6
|
+
### v0.25
|
7
|
+
* Added symbol matchers, which are basically just named regex. Only two symbol matchers included by default, `:numeric` and `:alpha_numeric`. It's intended that users add their own as per their applications requirements. E.g. `symbol_matchers[:article_id] = /[a-f][0-9]{4}/`. A symbol matcher can optionally take a two-element array, where the first element is the regex, and the second is a proc for the sake of coercing the matched value into the desired form, such as an integer.
|
8
|
+
* Changed Rack::Logger to Rack::CommonLogger.
|
9
|
+
|
6
10
|
### v0.24
|
7
11
|
* Query string is now preserved when stripping trailing slashes with `config[:strip_trailing_slash] = :redirect`, e.g. `/search/?query=cats` now becomes `/search?query=cats` instead of just `/search`.
|
8
12
|
* `absolute` method now returns as-is anything not starting with a forward slash, e.g. `absolute("./view") => "./view"`
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[Simple, Powerful, Scorched](
|
1
|
+
[Simple, Powerful, Scorched](https://scorchedrb.com)
|
2
2
|
==========================
|
3
3
|
|
4
4
|
Scorched is a generic, unopinionated, DRY, light-weight web framework for Ruby. It provides a generic yet powerful set of constructs for processing HTTP requests, with which websites and applications of almost any scale can be built.
|
@@ -109,12 +109,12 @@ This API shouldn't look too foreign to anyone familiar with frameworks like Sina
|
|
109
109
|
|
110
110
|
Comparisons with other frameworks
|
111
111
|
---------------------------------
|
112
|
-
Refer to the [comparisons](https://github.com/Wardrop/Scorched/tree/master/
|
112
|
+
Refer to the [comparisons](https://github.com/Wardrop/Scorched/tree/master/comparison) directory in the repo to compare a simple example app written in frameworks similar to Scorched.
|
113
113
|
|
114
114
|
Links
|
115
115
|
-----
|
116
|
-
* [Website](
|
117
|
-
* [Online API Reference](
|
118
|
-
* [GitHub Project](
|
119
|
-
* [Issue Tracker](
|
116
|
+
* [Website](https://scorchedrb.com)
|
117
|
+
* [Online API Reference](https://rubydoc.info/gems/scorched)
|
118
|
+
* [GitHub Project](https://github.com/wardrop/Scorched)
|
119
|
+
* [Issue Tracker](https://github.com/wardrop/Scorched/issues)
|
120
120
|
* [Discussion/Mailing List](https://groups.google.com/d/forum/scorched)
|
data/TODO.md
CHANGED
@@ -11,3 +11,10 @@ These features are unlikely to be implemented unless someone provides good enoug
|
|
11
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
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.
|
13
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.
|
14
|
+
|
15
|
+
Refactor Considerations
|
16
|
+
=======================
|
17
|
+
If I undergo a significant refactor of Scorched, here's a list of things I'd like to improve:
|
18
|
+
|
19
|
+
* Create a basic plugin system for optional features which may incur a performance and/or complexity overhead, e.g. Symbol matchers, content for. This will also negate the need for any kind of `contrib` library.
|
20
|
+
* Make route dispatching more modular, perhaps by simply breaking it out into more individual methods, making it more practical to override default behaviour.
|
@@ -41,8 +41,7 @@ In the latter of the two examples above, a `:method` condition defines what meth
|
|
41
41
|
|
42
42
|
Pattern Matching
|
43
43
|
----------------
|
44
|
-
All patterns attempt to match the remaining unmatched portion of the _request path_; the _request path_ being Rack's
|
45
|
-
`path_info` request variable. The unmatched path will always begin with a forward slash if the previously matched portion of the path ended immediately before, or included as the last character, a forward slash. As an example, if the request was to "/article/21", then both "/article/" => "/21" and "/article" => "/21" would match.
|
44
|
+
All patterns attempt to match the remaining unmatched portion of the _request path_; the _request path_ being Rack's `path_info` request variable. The unmatched path will always begin with a forward slash if the previously matched portion of the path ended immediately before, or included as the last character, a forward slash. As an example, if the request was to "/article/21", then both "/article/" => "/21" and "/article" => "/21" would match.
|
46
45
|
|
47
46
|
The `path_info` used to match against is unescaped, meaning percent-codes are resolved, e.g. `%20` resolves to a space. The two exceptions are the escaped forward-slash and percent sign, which remain escaped as `%2F` and `%25` respectively.
|
48
47
|
|
@@ -65,7 +64,30 @@ String patterns are compiled into Regexp patterns corresponding to the following
|
|
65
64
|
* `$` - If placed at the end of a pattern, the pattern only matches if it matches the entire path. For patterns defined using the route helpers, e.g. `Controller.route`, `Controller.get`, this is implied.
|
66
65
|
|
67
66
|
###Regex Patterns
|
68
|
-
Regex patterns offer more power and flexibility than string patterns (naturally). The rules for Regex patterns are identical to String patterns, e.g. they must match from the beginning of the path, etc.
|
67
|
+
Regex patterns offer more power and flexibility than string patterns (naturally). The rules for Regex patterns are identical to String patterns, e.g. they must match from the beginning of the path, etc.
|
68
|
+
|
69
|
+
###Symbol Matchers
|
70
|
+
Symbol matchers were added in v0.25 as a way to conveniently name and re-use regular expressions for matching. Additionally, symbol matchers allow one to define a Proc to pre-process the matched string. This can be used to coerce a value into a particular type (such as an integer), or to manipulate the string in some other way.
|
71
|
+
|
72
|
+
Two symbol matchers are included. `:numeric` and `:alpha_numeric`. These are more for example sake than anything else, as it's intended users will implement symbol matchers specific to their application. For example:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
symbol_matchers[:article_id] = /[a-z0-9\-]+-[0-9]{1,6}/
|
76
|
+
```
|
77
|
+
|
78
|
+
The above symbol matcher would match an article id in a typical blog friendly-URL, e.g. hello-world-453. We can further improve this symbol matcher by using a Proc to remove everything but the numeric id at the end, converting it to an integer at the same time.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
symbol_matchers[:article_id] =[/[a-z0-9\-]+-([0-9]{1,6})/, proc { |v| v.split('-').last.to_i }]
|
82
|
+
```
|
83
|
+
|
84
|
+
One limitation to be aware of is that like named captures, if you use the same symbol matcher more than once in a single pattern, you only be able to access the first capture.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
get '/:article_id/:article_id' do
|
88
|
+
captures[:article_id] #=> Will always equal the value of whatever first :article_id captured.
|
89
|
+
end
|
90
|
+
```
|
69
91
|
|
70
92
|
Captures
|
71
93
|
--------
|
data/lib/scorched/controller.rb
CHANGED
@@ -7,6 +7,7 @@ module Scorched
|
|
7
7
|
include Scorched::Options('config')
|
8
8
|
include Scorched::Options('render_defaults')
|
9
9
|
include Scorched::Options('conditions')
|
10
|
+
include Scorched::Options('symbol_matchers')
|
10
11
|
include Scorched::Collection('middleware')
|
11
12
|
include Scorched::Collection('before_filters')
|
12
13
|
include Scorched::Collection('after_filters', true)
|
@@ -84,13 +85,18 @@ module Scorched
|
|
84
85
|
},
|
85
86
|
}
|
86
87
|
|
88
|
+
symbol_matchers << {
|
89
|
+
numeric: [/(\d+)/, proc { |x| x.to_i }],
|
90
|
+
alpha_numeric: /([\da-z]+)/i
|
91
|
+
}
|
92
|
+
|
87
93
|
middleware << proc { |controller|
|
88
94
|
use Rack::Head
|
89
95
|
use Rack::MethodOverride
|
90
96
|
use Rack::Accept
|
91
97
|
use Scorched::Accept::Rack
|
92
98
|
use Scorched::Static, controller.config[:static_dir] if controller.config[:static_dir]
|
93
|
-
use Rack::
|
99
|
+
use Rack::CommonLogger, controller.config[:logger] if controller.config[:logger]
|
94
100
|
use Rack::ShowExceptions if controller.config[:show_exceptions]
|
95
101
|
}
|
96
102
|
|
@@ -228,7 +234,13 @@ module Scorched
|
|
228
234
|
if %w{* **}.include? match
|
229
235
|
match == '*' ? "([^/]#{op})" : "(.#{op})"
|
230
236
|
elsif match
|
231
|
-
match[0..1] == '::'
|
237
|
+
if match[0..1] == '::'
|
238
|
+
"(?<#{match[2..-1]}>.#{op})"
|
239
|
+
else
|
240
|
+
name = match[1..-1].to_sym
|
241
|
+
regexp = symbol_matchers[name] ? [*symbol_matchers[name]][0] : "[^/]"
|
242
|
+
"(?<#{name}>#{regexp}#{op})"
|
243
|
+
end
|
232
244
|
else
|
233
245
|
''
|
234
246
|
end
|
@@ -351,7 +363,10 @@ module Scorched
|
|
351
363
|
if match_data.names.empty?
|
352
364
|
captures = match_data.captures
|
353
365
|
else
|
354
|
-
captures = Hash[match_data.names.map{|v| v.to_sym}.zip
|
366
|
+
captures = Hash[match_data.names.map {|v| v.to_sym}.zip(match_data.captures)]
|
367
|
+
captures.each do |k,v|
|
368
|
+
captures[k] = symbol_matchers[k][1].call(v) if Array === symbol_matchers[k]
|
369
|
+
end
|
355
370
|
end
|
356
371
|
Match.new(mapping, captures, match_data.to_s, check_for_failed_condition(mapping[:conditions]))
|
357
372
|
end
|
data/lib/scorched/version.rb
CHANGED
data/spec/controller_spec.rb
CHANGED
@@ -176,6 +176,22 @@ module Scorched
|
|
176
176
|
req.captures.should == {name: 'jeff', infliction: 'has/crabs'}
|
177
177
|
end
|
178
178
|
|
179
|
+
it "can use symbol matchers" do
|
180
|
+
app << {pattern: '/:numeric', target: proc { |env| [200, {}, ['ok']] }}
|
181
|
+
rt.get('/45').status.should == 200
|
182
|
+
rt.get('/dog45').status.should == 404
|
183
|
+
req = nil
|
184
|
+
app << {pattern: '/:alpha_numeric', target: proc { |env| req = request; [200, {}, ['ok']] }}
|
185
|
+
rt.get('/dog45').status.should == 200
|
186
|
+
req.captures[:alpha_numeric].should == 'dog45'
|
187
|
+
rt.get('/_dog45').status.should == 404
|
188
|
+
end
|
189
|
+
|
190
|
+
it "can coerce symbol-matched values" do
|
191
|
+
app << {pattern: '/:numeric', target: proc { |env| [200, {}, [request.captures[:numeric].class.name]] }}
|
192
|
+
rt.get('/45').body.should == 'Fixnum'
|
193
|
+
end
|
194
|
+
|
179
195
|
it "matches routes based on priority, otherwise giving precedence to those defined first" do
|
180
196
|
order = []
|
181
197
|
app << {pattern: '/', priority: -1, target: proc { |env| order << 'four'; [200, {}, ['ok']] }}
|
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.25'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Wardrop
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -191,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
191
|
version: '0'
|
192
192
|
requirements: []
|
193
193
|
rubyforge_project:
|
194
|
-
rubygems_version: 2.
|
194
|
+
rubygems_version: 2.5.1
|
195
195
|
signing_key:
|
196
196
|
specification_version: 4
|
197
197
|
summary: Light-weight, DRY as a desert, web framework for Ruby
|