sinatra-url 0.0.1

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.
@@ -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: []