sinatra-url 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ require "rake/testtask"
2
+
3
+ begin
4
+ require "hanna/rdoctask"
5
+ rescue LoadError
6
+ require "rake/rdoctask"
7
+ end
8
+
9
+ Rake::RDocTask.new do |rd|
10
+ rd.main = "README"
11
+ rd.title = "API Documentation for Sinatra::Urls"
12
+ rd.rdoc_files.include("README", "LICENSE", "lib/**/*.rb")
13
+ rd.rdoc_dir = "doc"
14
+ end
15
+
16
+ begin
17
+ require "mg"
18
+ MG.new("sinatra-urls.gemspec")
19
+
20
+ task :build => :vendor
21
+ rescue LoadError
22
+ end
23
+
24
+ desc "Default: run tests"
25
+ task :default => :test
26
+
27
+ Rake::TestTask.new
@@ -0,0 +1,116 @@
1
+ require "sinatra/base"
2
+
3
+ module Sinatra
4
+ module URL
5
+ def self.extended(app)
6
+ app.module_eval do
7
+ extend DSL
8
+ include Helpers
9
+ end
10
+ end
11
+
12
+ class Mapper
13
+ def self.default
14
+ @default ||= new
15
+ end
16
+
17
+ def initialize
18
+ @map = {}
19
+ end
20
+
21
+ def [](name)
22
+ @map[name]
23
+ end
24
+
25
+ def []=(name, path)
26
+ @map[name] = Route.new(path)
27
+ end
28
+ end
29
+
30
+ class Route
31
+ def initialize(path)
32
+ @path = path
33
+ @pattern, @keys = compile(path)
34
+ end
35
+
36
+ def match(str)
37
+ @pattern.match(str)
38
+ end
39
+
40
+ def keys
41
+ @keys
42
+ end
43
+
44
+ def call(params)
45
+ params[:splat] = Array(params[:splat])
46
+ url = @path.dup
47
+
48
+ keys.each do |key|
49
+ match = key == "splat" ? "*" : ":#{key}"
50
+ value = key == "splat" ? params[:splat].shift : params[key.to_sym]
51
+ replacement = to_param(value)
52
+
53
+ unless url.sub! match, replacement
54
+ get_params[key] = params[key.to_sym]
55
+ end
56
+ end
57
+
58
+ get_params = {}
59
+ params.each do |key, value|
60
+ get_params[key] = to_param(value) unless
61
+ key == :splat || keys.include?(key.to_s)
62
+ end
63
+
64
+ url << "?" + Rack::Utils.build_query(get_params) unless get_params.empty?
65
+ url
66
+ end
67
+
68
+ private
69
+
70
+ def to_param(obj)
71
+ obj.respond_to?(:to_param) ? obj.to_param : obj.to_s
72
+ end
73
+
74
+ def compile(path)
75
+ keys = []
76
+ if path.respond_to? :to_str
77
+ special_chars = %w{. + ( )}
78
+ pattern =
79
+ path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
80
+ case match
81
+ when "*"
82
+ keys << 'splat'
83
+ "(.*?)"
84
+ when *special_chars
85
+ Regexp.escape(match)
86
+ else
87
+ keys << $2[1..-1]
88
+ "([^/?&#]+)"
89
+ end
90
+ end
91
+ [/^#{pattern}$/, keys]
92
+ elsif path.respond_to? :match
93
+ [path, keys]
94
+ else
95
+ raise TypeError, path
96
+ end
97
+ end
98
+ end
99
+
100
+ module DSL
101
+ def url(name, path=nil)
102
+ Mapper.default[name] = path unless path.nil?
103
+ Mapper.default[name] or raise ArgumentError, "Unregistered path for '#{name}'"
104
+ end
105
+ end
106
+
107
+ module Helpers
108
+ def url_for(name, params={})
109
+ route = Mapper.default[name] or raise ArgumentError, "Unregistered path for '#{name}'"
110
+ route.call(params)
111
+ end
112
+ end
113
+ end
114
+
115
+ register URL
116
+ end
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "sinatra-url"
3
+ s.version = "0.0.1"
4
+ s.description = "Simple sinatra extension that gives you the ability to use named URLs in your code"
5
+ s.summary = "Named URLs for Sinatra apps"
6
+ s.authors = ["Nicolas Sanguinetti"]
7
+ s.email = "hi@nicolassanguinetti.info"
8
+ s.homepage = "http://github.com/foca/sinatra-url"
9
+ s.has_rdoc = false
10
+ s.files = `git ls-files`.split "\n"
11
+ s.platform = Gem::Platform::RUBY
12
+
13
+ s.add_dependency("sinatra")
14
+ end
@@ -0,0 +1,34 @@
1
+ require "test/unit"
2
+ require "contest"
3
+ require "rack/test"
4
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/sinatra/url")
5
+
6
+ begin
7
+ require "redgreen"
8
+ rescue LoadError
9
+ end
10
+
11
+ if ENV["DEBUG"]
12
+ require "ruby-debug"
13
+ else
14
+ def debugger
15
+ puts "Run your tests with DEBUG=1 to use the debugger"
16
+ end
17
+ end
18
+
19
+ class Sinatra::TestApp < Sinatra::Base
20
+ include Test::Unit::Assertions
21
+ register Sinatra::URL
22
+ end
23
+
24
+ Sinatra::Base.set :environment, :test
25
+
26
+ class Test::Unit::TestCase
27
+ include Rack::Test::Methods
28
+
29
+ attr_reader :app
30
+
31
+ def mock_app(base=Sinatra::TestApp, &block)
32
+ @app = Sinatra.new(base, &block)
33
+ end
34
+ end
@@ -0,0 +1,108 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/test_helper")
2
+
3
+ class TestUrl < Test::Unit::TestCase
4
+ context "registering handlers with the url DSL" do
5
+ test "registers urls at the DSL level and gives you access to them at the helper level" do
6
+ mock_app {
7
+ get url(:foo, "/foo") do
8
+ assert_equal "/foo", url_for(:foo)
9
+ end
10
+ }
11
+ get "/foo"
12
+ assert last_response.ok?
13
+ end
14
+
15
+ test "can register a url with parameters" do
16
+ mock_app {
17
+ get url(:foo, "/foo/:name") do |name|
18
+ assert_equal "bar", name
19
+ end
20
+ }
21
+ get "/foo/bar"
22
+ assert last_response.ok?
23
+ end
24
+
25
+ test "can register an url without specifying a path if already registered" do
26
+ mock_app {
27
+ post url(:foo, "/foo/:name") do |name|
28
+ assert_equal "bar", name
29
+ end
30
+
31
+ get url(:foo) do |name|
32
+ assert_equal "bar", name
33
+ end
34
+ }
35
+ get "/foo/bar"
36
+ assert last_response.ok?
37
+ end
38
+
39
+ end
40
+
41
+ context "generating urls with url_for for registered handlers" do
42
+ test "generating urls with :named_params" do
43
+ mock_app {
44
+ get url(:foo, "/foo/:name") do |name|
45
+ assert_equal "/foo/bar", url_for(:foo, :name => "bar")
46
+ end
47
+ }
48
+ get "/foo/bar"
49
+ assert last_response.ok?
50
+ end
51
+
52
+ test "generating urls with :named_params using integer" do
53
+ mock_app {
54
+ get url(:foo, "/foo/:id") do |name|
55
+ assert_equal "/foo/10", url_for(:foo, :id => 10)
56
+ end
57
+ }
58
+ get "/foo/10"
59
+ assert last_response.ok?
60
+ end
61
+
62
+ test "generating urls with :named_params using object responding to #to_param" do
63
+ mock_app {
64
+ get url(:foo, "/foo/:name") do |name|
65
+ obj = Object.new
66
+ def obj.to_param; "toparam"; end
67
+
68
+ assert_equal "/foo/toparam", url_for(:foo, :name => obj)
69
+ end
70
+ }
71
+ get "/foo/toparam"
72
+ assert last_response.ok?
73
+ end
74
+
75
+ test "generating urls with splat args" do
76
+ mock_app {
77
+ get url(:foo, "/say/*/to/*") do
78
+ assert_equal "/say/hi/to/mom", url_for(:foo, :splat => ["hi", "mom"])
79
+ end
80
+ }
81
+ get "/say/hi/to/mom"
82
+ assert last_response.ok?
83
+ end
84
+
85
+ test "generating urls with extra arguments for GET" do
86
+ mock_app {
87
+ get url(:foo, "/foo/:name") do |name|
88
+ assert_equal "/foo/bar?get=param", url_for(:foo, :name => "bar", :get => 'param')
89
+ end
90
+ }
91
+ get "/foo/bar"
92
+ assert last_response.ok?
93
+ end
94
+ end
95
+
96
+ context "generating urls with url_for for unregistered handlers" do
97
+ test "should raise ArgumentError" do
98
+ assert_raise ArgumentError do
99
+ mock_app {
100
+ get "/" do
101
+ url_for(:unknown)
102
+ end
103
+ }
104
+ get "/"
105
+ end
106
+ end
107
+ end
108
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-url
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nicolas Sanguinetti
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: &70311744499800 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70311744499800
25
+ description: Simple sinatra extension that gives you the ability to use named URLs
26
+ in your code
27
+ email: hi@nicolassanguinetti.info
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - Rakefile
33
+ - lib/sinatra/url.rb
34
+ - sinatra-urls.gemspec
35
+ - test/test_helper.rb
36
+ - test/test_url.rb
37
+ homepage: http://github.com/foca/sinatra-url
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.11
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Named URLs for Sinatra apps
61
+ test_files: []