sinatra-snap 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +41 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/examples/named_route_example.rb +41 -0
- data/lib/sinatra/named_path_support.rb +72 -0
- data/lib/sinatra-snap.rb +1 -0
- data/sinatra-snap.gemspec +49 -0
- data/spec/snap_spec.rb +92 -0
- data/spec/spec_helper.rb +20 -0
- metadata +76 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Brandon Carlson (bcarlso)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
= Sinatra NAmed Paths (snap)
|
2
|
+
|
3
|
+
Enables named paths in Sinatra apps.
|
4
|
+
|
5
|
+
The SNAP extension is a solution for named paths in Sinatra. It also provides helper methods to
|
6
|
+
build URLs and perform parameter substitution.
|
7
|
+
|
8
|
+
Install the gem:
|
9
|
+
|
10
|
+
sudo gem install snap
|
11
|
+
|
12
|
+
Then require it in your application and use away!
|
13
|
+
|
14
|
+
require 'rubygems'
|
15
|
+
require 'sinatra'
|
16
|
+
require 'snap'
|
17
|
+
|
18
|
+
paths :add => '/add/:addend/:augend',
|
19
|
+
:sum => '/sum/:addend/:augend',
|
20
|
+
:subtract => '/subtract/*/*',
|
21
|
+
:difference => %r{/difference/(\d+)/(\d+)}
|
22
|
+
|
23
|
+
get :add do
|
24
|
+
redirect path_to(:sum).with(params[:addend], params[:augend])
|
25
|
+
end
|
26
|
+
|
27
|
+
get :sum do
|
28
|
+
"#{params[:addend]} + #{params[:augend]} = #{params[:addend].to_i + params[:augend].to_i}"
|
29
|
+
end
|
30
|
+
|
31
|
+
get :subtract do
|
32
|
+
redirect path_to(:difference).with(params[:splat][0], params[:splat][1])
|
33
|
+
end
|
34
|
+
|
35
|
+
get :difference do
|
36
|
+
"#{params[:captures][0]} - #{params[:captures[1]]} = #{params[:captures][0]].to_i - params[:captures][1]].to_i}"
|
37
|
+
end
|
38
|
+
|
39
|
+
== Copyright
|
40
|
+
|
41
|
+
Copyright (c) 2009 Brandon Carlson (bcarlso). See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "sinatra-snap"
|
8
|
+
gem.summary = "Sinatra NAmed Path support"
|
9
|
+
gem.email = "bcarlso@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/bcarlso/snap"
|
11
|
+
gem.authors = ["bcarlso"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
end
|
14
|
+
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'spec/rake/spectask'
|
20
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
21
|
+
spec.libs << 'lib' << 'spec'
|
22
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
28
|
+
spec.rcov = true
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task :default => :spec
|
33
|
+
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
if File.exist?('VERSION.yml')
|
37
|
+
config = YAML.load(File.read('VERSION.yml'))
|
38
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
39
|
+
else
|
40
|
+
version = ""
|
41
|
+
end
|
42
|
+
|
43
|
+
rdoc.rdoc_dir = 'rdoc'
|
44
|
+
rdoc.title = "snap #{version}"
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
48
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'sinatra-snap'
|
4
|
+
|
5
|
+
path :home => '/index'
|
6
|
+
paths :add => '/add/:augend/:addend',
|
7
|
+
:sum => '/sum/:augend/:addend',
|
8
|
+
:subtract => '/subtract/*/*',
|
9
|
+
:difference => %r{/difference/(\d+)/(\d+)}
|
10
|
+
|
11
|
+
get :home do
|
12
|
+
"Hello World!"
|
13
|
+
end
|
14
|
+
|
15
|
+
get :add do
|
16
|
+
redirect(path_to(:sum).with(params[:augend], params[:addend]))
|
17
|
+
end
|
18
|
+
|
19
|
+
get :sum do
|
20
|
+
"#{params[:augend]} + #{params[:addend]} = #{params[:augend].to_i + params[:addend].to_i}"
|
21
|
+
end
|
22
|
+
|
23
|
+
get :subtract do
|
24
|
+
redirect path_to(:difference).with(params[:splat][0], params[:splat][1])
|
25
|
+
end
|
26
|
+
|
27
|
+
get :difference do
|
28
|
+
"#{params[:captures][0]} - #{params[:captures][1]} = #{params[:captures][0].to_i - params[:captures][1].to_i}"
|
29
|
+
end
|
30
|
+
|
31
|
+
path :hello => '/hi/:name'
|
32
|
+
|
33
|
+
get '/index.html' do
|
34
|
+
url = path_to(:hello).with('bcarlso')
|
35
|
+
"<a href='#{url}'>xxx</a>"
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
get :hello do
|
40
|
+
"Hi #{params[:name]}"
|
41
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module PathDefinitionSupport
|
5
|
+
def self.registered(app)
|
6
|
+
app.set :named_paths, {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def paths(paths)
|
10
|
+
paths.keys.each { | k | verify_type_of(k) }
|
11
|
+
named_paths.merge!(paths)
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :path, :paths
|
15
|
+
|
16
|
+
def route(verb, path, options={}, &block)
|
17
|
+
path = named_paths[path] if path.kind_of? Symbol
|
18
|
+
super verb, path, options, &block
|
19
|
+
end
|
20
|
+
|
21
|
+
def verify_type_of(name)
|
22
|
+
raise ArgumentError.new('Path name must be a symbol') unless name.kind_of?(Symbol)
|
23
|
+
end
|
24
|
+
|
25
|
+
private :verify_type_of
|
26
|
+
end
|
27
|
+
|
28
|
+
module PathBuilderSupport
|
29
|
+
def path_to path_name
|
30
|
+
pattern = self.class.named_paths[path_name]
|
31
|
+
puts "----------> " + path_name.to_s
|
32
|
+
pattern.instance_eval do
|
33
|
+
def with(*values)
|
34
|
+
if self.instance_of? Regexp
|
35
|
+
process_regex_replacement(values)
|
36
|
+
else
|
37
|
+
process_string_replacement(values)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def process_regex_replacement(values)
|
42
|
+
url = String.new(self.source)
|
43
|
+
self.source.scan(%r{\(.+?\)}).each_with_index do | placeholder, index |
|
44
|
+
url.sub!(Regexp.new(Regexp.escape(placeholder)), values[index].to_s)
|
45
|
+
end
|
46
|
+
url
|
47
|
+
end
|
48
|
+
|
49
|
+
def process_string_replacement(values)
|
50
|
+
if %r{/(\*)}.match self
|
51
|
+
replacement_pattern = %r{/(\*)}
|
52
|
+
else
|
53
|
+
replacement_pattern = %r{/?(:\S+?)(?:/|$)}
|
54
|
+
end
|
55
|
+
build_url_from(replacement_pattern, values)
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_url_from(replacement_pattern, values)
|
59
|
+
url = String.new(self)
|
60
|
+
scan(replacement_pattern).each_with_index do | placeholder, index |
|
61
|
+
url.sub!(Regexp.new(Regexp.escape(placeholder[0])), values[index].to_s)
|
62
|
+
end
|
63
|
+
url
|
64
|
+
end
|
65
|
+
end
|
66
|
+
pattern
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
register PathDefinitionSupport
|
71
|
+
helpers PathBuilderSupport
|
72
|
+
end
|
data/lib/sinatra-snap.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/sinatra/named_path_support'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{sinatra-snap}
|
5
|
+
s.version = "0.3.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["bcarlso"]
|
9
|
+
s.date = %q{2010-03-06}
|
10
|
+
s.email = %q{bcarlso@gmail.com}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"LICENSE",
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"examples/named_route_example.rb",
|
23
|
+
"lib/sinatra/named_path_support.rb",
|
24
|
+
"lib/sinatra-snap.rb",
|
25
|
+
"sinatra-snap.gemspec",
|
26
|
+
"spec/snap_spec.rb",
|
27
|
+
"spec/spec_helper.rb"
|
28
|
+
]
|
29
|
+
s.homepage = %q{http://github.com/bcarlso/sinatra-snap}
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
s.rubygems_version = %q{1.3.5}
|
33
|
+
s.summary = %q{Sinatra NAmed Path support}
|
34
|
+
s.test_files = [
|
35
|
+
"spec/snap_spec.rb",
|
36
|
+
"spec/spec_helper.rb",
|
37
|
+
"examples/named_route_example.rb"
|
38
|
+
]
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
45
|
+
else
|
46
|
+
end
|
47
|
+
else
|
48
|
+
end
|
49
|
+
end
|
data/spec/snap_spec.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'rack/test'
|
4
|
+
|
5
|
+
describe "Snap DSL extensions" do
|
6
|
+
before :each do
|
7
|
+
create_and_register_snap
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should extend the route method to support passing in symbols" do
|
11
|
+
@app.path :home => 'homepage'
|
12
|
+
@app.get :home do
|
13
|
+
'irrelavent'
|
14
|
+
end
|
15
|
+
|
16
|
+
verify_route_added('GET', 'homepage')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should initialize the named paths collection when registered" do
|
20
|
+
@app.named_paths.should be_empty
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should register a new named path when the path method is called" do
|
24
|
+
@app.path :name => '/url'
|
25
|
+
@app.named_paths.should == { :name => '/url' }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should register a collection of named paths when the paths method is called" do
|
29
|
+
@app.paths :names => '/url',
|
30
|
+
:other_name => '/other_url'
|
31
|
+
@app.named_paths.should == { :names => '/url',
|
32
|
+
:other_name => '/other_url' }
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should only allow symbols to be passed in as the first parameter of a path call" do
|
36
|
+
begin
|
37
|
+
@app.path 'anything other than a symbol', '/irrelavent-for-this-test'
|
38
|
+
fail
|
39
|
+
rescue ArgumentError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should only allow symbols to be passed in as the key to the paths hash" do
|
44
|
+
begin
|
45
|
+
@app.paths 'anything other than a symbol' => '/irrelavent-for-this-test',
|
46
|
+
:name => '/also-irrelavent'
|
47
|
+
fail
|
48
|
+
rescue ArgumentError
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "Snap helper methods for building URLs" do
|
54
|
+
before :each do
|
55
|
+
create_and_register_snap
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return a simple path using path_to" do
|
59
|
+
@app.path :name => '/url'
|
60
|
+
@app.new.path_to(:name).should == '/url'
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should retrieve a path by key and perform parameter substitution" do
|
64
|
+
@app.path :users => '/users/:name/tags/:tag'
|
65
|
+
@app.new.path_to(:users).with('bcarlso', 'sinatra').should == '/users/bcarlso/tags/sinatra'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should retrieve a path by key and perform parameter substitution on numeric values" do
|
69
|
+
@app.path :users => '/users/:id'
|
70
|
+
@app.new.path_to(:users).with(15).should == '/users/15'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should retrieve a path by key and perform parameter substitution on consecutive placeholders" do
|
74
|
+
@app.path :users => '/users/:id/:age'
|
75
|
+
@app.new.path_to(:users).with(15, 23).should == '/users/15/23'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should retrieve a path defined as a regex and perform parameter substitution" do
|
79
|
+
@app.path :users => %r{/users/(\d+)}
|
80
|
+
@app.new.path_to(:users).with(15).should == '/users/15'
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should retrieve a path defined as a regex and perform parameter substitution on consecutive parameters" do
|
84
|
+
@app.path :users => %r{/users/(\d+)/(foo|bar)}
|
85
|
+
@app.new.path_to(:users).with(15, 'foo').should == '/users/15/foo'
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should support splat syntax" do
|
89
|
+
@app.path :say => '/say/*/to/*'
|
90
|
+
@app.new.path_to(:say).with('hi', 'bob').should == '/say/hi/to/bob'
|
91
|
+
end
|
92
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'spec'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'sinatra/named_path_support'
|
7
|
+
|
8
|
+
Spec::Runner.configure do |config|
|
9
|
+
def create_and_register_snap
|
10
|
+
@app = Sinatra.new
|
11
|
+
@app.register Sinatra::PathDefinitionSupport
|
12
|
+
@app.helpers Sinatra::PathBuilderSupport
|
13
|
+
end
|
14
|
+
|
15
|
+
def verify_route_added(verb, path)
|
16
|
+
routes = @app.routes[verb]
|
17
|
+
routes.size.should == 1
|
18
|
+
routes[0][0].should match(path)
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-snap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 0.3.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- bcarlso
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-06 00:00:00 -06:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description:
|
22
|
+
email: bcarlso@gmail.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- .document
|
32
|
+
- .gitignore
|
33
|
+
- LICENSE
|
34
|
+
- README.rdoc
|
35
|
+
- Rakefile
|
36
|
+
- VERSION
|
37
|
+
- examples/named_route_example.rb
|
38
|
+
- lib/sinatra/named_path_support.rb
|
39
|
+
- lib/sinatra-snap.rb
|
40
|
+
- sinatra-snap.gemspec
|
41
|
+
- spec/snap_spec.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: http://github.com/bcarlso/sinatra-snap
|
45
|
+
licenses: []
|
46
|
+
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --charset=UTF-8
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.6
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Sinatra NAmed Path support
|
73
|
+
test_files:
|
74
|
+
- spec/snap_spec.rb
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
- examples/named_route_example.rb
|