simple_router 0.9.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/
2
+ doc/
3
+ *.gem
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright © 2009 Martin Aumont (mynyml)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,17 @@
1
+ .gitignore
2
+ LICENSE
3
+ Manifest
4
+ README.md
5
+ Rakefile
6
+ TODO
7
+ examples/rack_app.ru
8
+ lib/simple_router.rb
9
+ lib/simple_router/dsl.rb
10
+ lib/simple_router/engines/simple_engine.rb
11
+ lib/simple_router/routes.rb
12
+ simple_router.gemspec
13
+ test/engines/test_simple_engine.rb
14
+ test/test_dsl.rb
15
+ test/test_helper.rb
16
+ test/test_routes.rb
17
+ test/test_simple_router.rb
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+
2
+ Summary
3
+ -------
4
+ Small and simple standalone router, meant for use with Rack applications.
5
+
6
+ Features
7
+ --------
8
+ * Familiar Sinatra-like DSL for defining actions
9
+ * Modular architecture (see ROUTING ENGINES section)
10
+ * No magic
11
+ * Low level / Highly flexible
12
+ * Simple code
13
+
14
+ Examples
15
+ --------
16
+
17
+ class App
18
+ include SimpleRouter::DSL
19
+
20
+ get '/' do
21
+ 'home'
22
+ end
23
+
24
+ get '/archives/:year/:month/:day' do |year, month, day|
25
+ Article.archived.find_by_date(year, month, day)
26
+ end
27
+
28
+ def call(env)
29
+ verb, path = ENV['REQUEST_METHOD'], ENV['PATH_INFO']
30
+ route = self.class.routes.match(verb, path)
31
+ route.nil? ?
32
+ [404, {'Content-Type' => 'text/html'}, '404 page not found'] :
33
+ [200, {'Content-Type' => 'text/html'}, route.action.call(*route.values)]
34
+ end
35
+ end
36
+
37
+ The SimpleRouter::DSL mixin provides 5 class methods:
38
+
39
+ #get, #post, #put, #delete and #routes
40
+
41
+ The four verb methods allow you to define actions that will match a request for
42
+ the verb and route signature it defines.
43
+
44
+ The #routes method responds to #match and will return the first matching route
45
+ (in order they were defined), and the values of the variables defined in the
46
+ route signature if any (:year, :month, ...).
47
+
48
+ Finally, the route returned is a simple object: for the second route in the
49
+ example above:
50
+
51
+ route.verb #=> :get
52
+ route.path #=> '/archives/:year/:month/:day'
53
+ route.action #=> lambda {|year, month, day| Article.archived.find_by_date(year, month, day) }
54
+ route.values #=> ['2008', '07', '01'] # after being matched with path '/archives/2008/07/01'
55
+
56
+ See examples/ directory for executable code examples.
57
+
58
+ Routing Engines
59
+ ---------------
60
+ By design, the code is seperated in two main components:
61
+
62
+ o DSL for defining routes/actions and retrieving requested action block.
63
+ o Routing engine
64
+
65
+ Different engines can be used by assigning them to the router:
66
+
67
+ SimpleRouter.engine = UltraFastEngine
68
+
69
+ This allows, for instance, a new faster engine to be used by an app without
70
+ changes in the top level DSL.
71
+
72
+ Engines can also allow route definitions to include more (or less!) features.
73
+ For example, the built-in SimpleEngine allows route variables and extension
74
+ handling. Others could add variable conditions ( :id => Integer ), mime-type
75
+ restrictions, etc.
76
+
77
+ #### Engine Writers
78
+
79
+ Engines only need to conform to a simple interface. See
80
+ lib/simple_router/engines/simple_engine.rb for details.
81
+
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ def gem_opt
2
+ defined?(Gem) ? "-rubygems" : ""
3
+ end
4
+
5
+ def ruby(path)
6
+ path = "-e'%w( #{path.join(' ')} ).each {|p| require p }'" if path.is_a?(Array)
7
+ system "ruby #{gem_opt} -I.:lib:test #{path}"
8
+ end
9
+
10
+ # --------------------------------------------------
11
+ # Tests
12
+ # --------------------------------------------------
13
+ task(:default => :test)
14
+
15
+ desc "Run tests"
16
+ task(:test) do
17
+ exit ruby( Dir['test/**/test_*.rb'] - ['test/test_helper.rb'] )
18
+ end
19
+
20
+ # --------------------------------------------------
21
+ # Docs
22
+ # --------------------------------------------------
23
+ desc "Generate YARD Documentation"
24
+ task(:yardoc) do
25
+ require 'yard'
26
+ files = %w( lib/**/*.rb )
27
+ options = %w( -o doc/yard --readme README.md --files LICENSE )
28
+ YARD::CLI::Yardoc.run *(options + files)
29
+ end
30
+
data/TODO ADDED
@@ -0,0 +1 @@
1
+ o improve docs
@@ -0,0 +1,45 @@
1
+ require 'pathname'
2
+ root = Pathname(__FILE__).dirname.parent.expand_path
3
+ $:.unshift(root.join('lib'))
4
+
5
+ # run me with:
6
+ # $rackup examples/rack_app.ru
7
+ # --------------------------------------------------
8
+ require 'rubygems'
9
+ require 'simple_router'
10
+
11
+ class App
12
+ include SimpleRouter::DSL
13
+
14
+ get '/' do |params|
15
+ <<-html
16
+ <pre>
17
+ params: #{params.inspect}
18
+ </pre>
19
+ html
20
+ end
21
+
22
+ get '/:foo.:type' do |foo, type, params|
23
+ <<-html
24
+ <pre>
25
+ foo: #{foo.inspect}
26
+ type: #{type.inspect}
27
+ params: #{params.inspect}
28
+ </pre>
29
+ html
30
+ end
31
+
32
+ def call(env)
33
+ request = Rack::Request.new(env)
34
+
35
+ verb = request.request_method.downcase.to_sym
36
+ path = Rack::Utils.unescape(request.path_info)
37
+
38
+ route = self.class.routes.match(verb, path)
39
+ route.nil? ?
40
+ [404, {'Content-Type' => 'text/html'}, '404 page not found'] :
41
+ [200, {'Content-Type' => 'text/html'}, [route.action.call(*route.values.push(request.params))]]
42
+ end
43
+ end
44
+
45
+ run App.new
@@ -0,0 +1,13 @@
1
+ module SimpleRouter
2
+ class << self
3
+ attr_accessor :engine
4
+ def engine() @engine || Engines::SimpleEngine end
5
+ end
6
+
7
+ autoload :DSL, 'simple_router/dsl'
8
+ autoload :Routes, 'simple_router/routes'
9
+
10
+ module Engines
11
+ autoload :SimpleEngine, 'simple_router/engines/simple_engine'
12
+ end
13
+ end
@@ -0,0 +1,57 @@
1
+ module SimpleRouter
2
+
3
+ # Mixin that provides a Sinatra-line DSL frontend to the routing engine
4
+ # backend.
5
+ #
6
+ # Meant to be minimal, simple and as magic-free as possible.
7
+ # When mixed in, only adds 5 class methods (#get, #post, #put, #delete and #routes).
8
+ #
9
+ # ==== Examples
10
+ # # simple rack app
11
+ #
12
+ # class App
13
+ # include SimpleRouter::DSL
14
+ #
15
+ # get '/' do
16
+ # 'home'
17
+ # end
18
+ #
19
+ # get '/users/:id' do |id|
20
+ # end
21
+ #
22
+ # put '/:foo/:bar' do |foo, bar, *params|
23
+ # end
24
+ #
25
+ # def call(env)
26
+ # request = Rack::Request.new(env)
27
+ #
28
+ # verb = request.request_method
29
+ # path = Rack::Utils.unescape(request.path_info)
30
+ #
31
+ # action = self.class.routes.match(verb, path).action
32
+ # action.nil? ? [404, {}, []] : [200, {}, [action.call]]
33
+ # end
34
+ # end
35
+ #
36
+ # ==== Notes
37
+ # Because the DSL is a simple mixin, it can be used in any class (i.e. not
38
+ # necessarily a rack app).
39
+ #
40
+ module DSL
41
+ def self.included(base)
42
+ base.extend(ClassMethods)
43
+ base.class_eval do
44
+ @routes = Routes.new
45
+ end
46
+ end
47
+
48
+ module ClassMethods
49
+ attr_reader :routes
50
+
51
+ def get( path, opts={}, &block) routes.add(:get, path, opts, &block) end
52
+ def post( path, opts={}, &block) routes.add(:post, path, opts, &block) end
53
+ def put( path, opts={}, &block) routes.add(:put, path, opts, &block) end
54
+ def delete(path, opts={}, &block) routes.add(:delete, path, opts, &block) end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,102 @@
1
+ require 'pathname'
2
+
3
+ module SimpleRouter
4
+ module Engines
5
+ module SimpleEngine #:nodoc:
6
+
7
+ def self.match(*args)
8
+ Base.match(*args)
9
+ end
10
+
11
+ class Base
12
+ # Finds a route definition that matches a path
13
+ #
14
+ # ===== Arguments
15
+ # * path: actual path to match (e.g. ENV['PATH_INFO'])
16
+ # * routes: array of 'routes', where each route is composed of [pattern, options]. If route isn't an array, an empty options hash is assumed
17
+ #
18
+ # Currently, this engine implementation ignores route options.
19
+ #
20
+ # ===== Returns
21
+ # Array of two elements:
22
+ #
23
+ # * index 0: first matching route
24
+ # * index 1: array of values for the matched route's variables (in the order they were specified in the route)
25
+ #
26
+ # ===== Examples
27
+ #
28
+ # SimpleEngine.match('/foo', ['/', '/foo', '/bar/baz']) #=> ['/foo', []]
29
+ # SimpleEngine.match('/80/07/01', ['/:year/:month/:day']) #=> ['/foo', ['80', '07', '01']]
30
+ #
31
+ def self.match(path, routes)
32
+ path = Path.new(path)
33
+ patterns = routes.map {|route| Pattern.new(Array(route).first) }
34
+
35
+ patterns.each do |pattern|
36
+ return [pattern.to_s, pattern.vars] if pattern == path
37
+ end
38
+
39
+ [nil, []]
40
+ end
41
+ end
42
+
43
+ class Path #:nodoc:
44
+ attr_accessor :parts, :ext
45
+
46
+ def initialize(path)
47
+ self.parts, self.ext = split_path(path)
48
+ end
49
+
50
+ def to_s
51
+ '/' + self.parts.join('/') + self.ext
52
+ end
53
+
54
+ private
55
+ def split_path(path)
56
+ path = path.to_s
57
+ ext = Pathname(path).extname
58
+ path = path.sub(/#{ext}$/,'')
59
+ parts = path.split('/').reject {|part| part.empty? }
60
+ [parts, ext]
61
+ end
62
+ end
63
+
64
+ class Pattern < Path #:nodoc:
65
+
66
+ def variables
67
+ return [] unless @match
68
+
69
+ a = []
70
+ self.parts.each_with_index do |part,i|
71
+ a << @match.parts[i] if part[0] == ?:
72
+ end
73
+ a << @match.ext[1..-1] if self.ext[1] == ?:
74
+ a
75
+ end
76
+ alias :vars :variables
77
+
78
+ def ==(path)
79
+ is_match = size_match?(path) && ext_match?(path) && static_match?(path)
80
+ @match = path if is_match
81
+ is_match
82
+ end
83
+
84
+ private
85
+ def size_match?(path)
86
+ self.parts.size == path.parts.size
87
+ end
88
+
89
+ def ext_match?(path)
90
+ (self.ext == path.ext) || (self.ext[1] == ?: && !path.ext.empty?)
91
+ end
92
+
93
+ def static_match?(path)
94
+ self.parts.each_with_index do |part,i|
95
+ return false unless part[0] == ?: || path.parts[i] == part
96
+ end
97
+ true
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,36 @@
1
+ module SimpleRouter
2
+ class Routes < Array
3
+
4
+ def add(*args, &action)
5
+ self << Route.new(*args, &action)
6
+ end
7
+
8
+ def match(verb, path)
9
+ return nil if self.empty?
10
+
11
+ verb = verb.to_s.downcase.strip.to_sym
12
+
13
+ routes = self.select {|route| route.verb == verb }
14
+ paths = routes.map {|route| route.path }
15
+
16
+ path, values = SimpleRouter.engine.match(path, paths)
17
+ return nil if path.nil?
18
+
19
+ route = routes.detect {|route| route.path == path }
20
+ route.values = values
21
+ route
22
+ end
23
+
24
+ class Route
25
+ attr_accessor :verb,:path,:options,:action, :values
26
+
27
+ def initialize(verb, path, options, &action)
28
+ self.verb = verb
29
+ self.path = path
30
+ self.options = options
31
+ self.action = action
32
+ self.values = nil
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'simple_router'
3
+ s.version = "0.9.8.1"
4
+ s.summary = "Simple, minimalistic, standalone router meant to be used with pure rack applications"
5
+ s.description = "Simple, minimalistic, standalone router meant to be used with pure rack applications."
6
+ s.author = "mynyml"
7
+ s.email = "mynyml@gmail.com"
8
+ s.homepage = "http://github.com/mynyml/simple_router"
9
+ s.rubyforge_project = "simple_router"
10
+ s.has_rdoc = true
11
+ s.require_path = "lib"
12
+ s.files = File.read("Manifest").strip.split("\n")
13
+
14
+ s.add_development_dependency 'rack'
15
+ s.add_development_dependency 'nanotest'
16
+ s.add_development_dependency 'nanotest_extensions'
17
+ end
@@ -0,0 +1,145 @@
1
+ require 'test/test_helper'
2
+
3
+ ## SimpleEngine
4
+ context do
5
+ include SimpleRouter::Engines::SimpleEngine
6
+
7
+ # matches static paths
8
+ test do
9
+ Base.match('/', ['/', '/foo']).first.must == '/'
10
+ Base.match('/foo', ['/', '/foo']).first.must == '/foo'
11
+ Base.match('/bar', ['/', '/foo']).first.must == nil
12
+ end
13
+
14
+ # matches variable paths
15
+ test do
16
+ path, vars = Base.match('/80/07', ['/foo', '/:year/:month'])
17
+ path.must == '/:year/:month'
18
+ vars.must == ['80','07']
19
+ end
20
+
21
+ # matches hybrid paths
22
+ test do
23
+ path, vars = Base.match('/archives/80/07', ['/foo', '/archives/:year/:month'])
24
+ path.must == '/archives/:year/:month'
25
+ vars.must == ['80','07']
26
+ end
27
+
28
+ # ignores leading slash in path
29
+ test do
30
+ path, vars = Base.match('archives/80/07', ['/foo', '/archives/:year/:month'])
31
+ path.must == '/archives/:year/:month'
32
+ vars.must == ['80','07']
33
+ end
34
+
35
+ # no matches
36
+ test do
37
+ path, vars = Base.match('/80/07/01', ['/foo', '/:year/:month'])
38
+ path.must == nil
39
+ vars.must == []
40
+ end
41
+
42
+ # treats extension as pattern part
43
+ test do
44
+ path, vars = Base.match('/a/b.xml', ['/:foo/:bar', '/:foo/:bar.:type'])
45
+ path.must == '/:foo/:bar.:type'
46
+ vars.must == ['a','b','xml']
47
+ end
48
+ end
49
+
50
+ ## Pattern
51
+ context do
52
+ include SimpleRouter::Engines::SimpleEngine
53
+
54
+ # static pattern matches a path
55
+ test do
56
+ path = Path.new('/foo/bar')
57
+ pattern = Pattern.new('/foo/bar')
58
+
59
+ assert { pattern == path }
60
+ end
61
+
62
+ # variable pattern matches a path
63
+ test do
64
+ path = Path.new('/foo/bar')
65
+ pattern = Pattern.new('/:foo/:bar')
66
+
67
+ assert { pattern == path }
68
+ end
69
+
70
+ # pattern variables
71
+ test do
72
+ path = Path.new('/foo/bar/baz')
73
+ pattern = Pattern.new('/:a/:b/:c')
74
+
75
+ assert { pattern == path }
76
+ pattern.vars.must == %w( foo bar baz )
77
+ end
78
+
79
+ # pattern variables with extension
80
+ test do
81
+ path = Path.new('/foo/bar/baz.xml')
82
+ pattern = Pattern.new('/:a/:b/:c.:type')
83
+
84
+ assert { pattern == path }
85
+ pattern.vars.must == %w( foo bar baz xml )
86
+ end
87
+
88
+ # variable pattern matches a path with static extension
89
+ test do
90
+ path = Path.new('/foo/bar.xml')
91
+ pattern = Pattern.new('/:foo/:bar.xml')
92
+
93
+ assert { pattern == path }
94
+ end
95
+
96
+ # variable pattern matches a path with variable extension
97
+ test do
98
+ path = Path.new('/foo/bar.xml')
99
+ pattern = Pattern.new('/:foo/:bar.:type')
100
+
101
+ assert { pattern == path }
102
+ end
103
+
104
+ # pattern without extension doesn't match path with extension
105
+ test do
106
+ path = Path.new('/foo/bar.xml')
107
+ pattern = Pattern.new('/:foo/:bar')
108
+
109
+ assert { pattern != path }
110
+ end
111
+
112
+ # pattern with static extension doesn't match path without extension
113
+ test do
114
+ path = Path.new('/foo/bar')
115
+ pattern = Pattern.new('/:foo/:bar.xml')
116
+
117
+ assert { pattern != path }
118
+ end
119
+
120
+ # pattern with variable extension doesn't match path without extension
121
+ test do
122
+ path = Path.new('/foo/bar')
123
+ pattern = Pattern.new('/:foo/:bar.:type')
124
+
125
+ assert { pattern != path }
126
+ end
127
+
128
+ # doesn't ignore dots in path parts
129
+ test do
130
+ path = Path.new('/foo/bar.baz/abc')
131
+ pattern = Pattern.new('/:a/:b/:c')
132
+
133
+ assert { pattern == path }
134
+ pattern.variables.must == %w( foo bar.baz abc )
135
+ end
136
+
137
+ # doesn't get confused with extension when path contains other dots
138
+ test do
139
+ path = Path.new('/foo/bar.baz/abc.xml')
140
+ pattern = Pattern.new('/:a/:b/:c.:type')
141
+
142
+ assert { pattern == path }
143
+ pattern.variables.must == %w( foo bar.baz abc xml )
144
+ end
145
+ end
data/test/test_dsl.rb ADDED
@@ -0,0 +1,45 @@
1
+ require 'test/test_helper'
2
+
3
+ class App
4
+ include SimpleRouter::DSL
5
+ end
6
+
7
+ context do
8
+
9
+ setup do
10
+ SimpleRouter.engine = SimpleRouter::Engines::SimpleEngine
11
+ end
12
+
13
+ teardown do
14
+ App.routes.clear
15
+ end
16
+
17
+ ## API
18
+
19
+ # provides action verb methods
20
+ test do
21
+ App.get( '/foo') {}
22
+ App.post( '/foo') {}
23
+ App.put( '/foo') {}
24
+ App.delete('/foo') {}
25
+
26
+ App.routes.size.must == 4
27
+ end
28
+
29
+ # provides routes object
30
+ test do
31
+ App.respond_to?(:routes).must == true
32
+ App.routes.must.kind_of?(SimpleRouter::Routes)
33
+ end
34
+
35
+ ## matching
36
+
37
+ # matching routes
38
+ test do
39
+ App.get('/foo') { 'foo' }
40
+ App.get('/bar') { 'bar' }
41
+
42
+ App.routes.match(:get, '/foo').wont == nil
43
+ App.routes.match(:get, '/foo').action.call.must == 'foo'
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ require 'pathname'
2
+ require 'nanotest'
3
+ require 'nanotest/spec'
4
+ require 'nanotest/contexts'
5
+ begin
6
+ require 'ruby-debug'
7
+ require 'redgreen' # gem install mynyml-redgreen
8
+ require 'nanotest/stats'
9
+ require 'nanotest/focus'
10
+ rescue LoadError, RuntimeError
11
+ end
12
+
13
+ $:.unshift Pathname(__FILE__).dirname.parent + 'lib'
14
+ require 'simple_router'
15
+
16
+ include Nanotest
17
+ include Nanotest::Contexts
@@ -0,0 +1,63 @@
1
+ require 'test/test_helper'
2
+
3
+ ## Routes
4
+ context do
5
+ Routes = SimpleRouter::Routes
6
+
7
+ setup do
8
+ @routes = Routes.new
9
+ @action = lambda {}
10
+ end
11
+
12
+ # stores route definitions
13
+ test do
14
+ @routes.add(:get, '/foo', {}, &@action)
15
+ @routes.first.path.must == '/foo'
16
+ end
17
+
18
+ ## matching
19
+
20
+ # matches a path
21
+ test do
22
+ @routes.add(:get, '/foo', {}, &@action)
23
+ @routes.add(:get, '/bar', {}, &@action)
24
+
25
+ @routes.match(:get, '/bar').wont == nil
26
+ @routes.match(:get, '/bar').path.must == '/bar'
27
+ end
28
+
29
+ # returns nil when no route matches
30
+ test do
31
+ @routes.add(:get, '/foo', {}, &@action)
32
+ @routes.add(:get, '/bar', {}, &@action)
33
+
34
+ @routes.match('/baz', :get).must == nil
35
+ end
36
+
37
+ # normalizes passed in verb string
38
+ test do
39
+ @routes.add(:get, '/foo', {}, &@action)
40
+ @routes.add(:get, '/bar', {}, &@action)
41
+
42
+ @routes.match('get', '/bar').path.must == '/bar'
43
+ @routes.match('GET', '/bar').path.must == '/bar'
44
+ @routes.match(' GET ','/bar').path.must == '/bar'
45
+ end
46
+ end
47
+
48
+ ## Route
49
+ context do
50
+
51
+ # internal API
52
+ test do
53
+ verb, path, options, action = :get, '/foo', {}, lambda {}
54
+
55
+ route = SimpleRouter::Routes::Route.new(verb, path, options, &action)
56
+ route.verb .must == verb
57
+ route.path .must == path
58
+ route.options .must == options
59
+ route.action .must == action
60
+ route.values .must == nil
61
+ end
62
+ end
63
+
@@ -0,0 +1,25 @@
1
+ require 'test/test_helper'
2
+
3
+ class App
4
+ include SimpleRouter::DSL
5
+ end
6
+
7
+ context do
8
+
9
+ setup do
10
+ SimpleRouter.engine = nil
11
+ end
12
+
13
+ ## engine
14
+
15
+ # default engine
16
+ test do
17
+ SimpleRouter.engine.name.split('::').last.must == 'SimpleEngine'
18
+ end
19
+
20
+ # custom engine
21
+ test do
22
+ SimpleRouter.engine = ::Object
23
+ SimpleRouter.engine.name.must == 'Object'
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_router
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.8.1
5
+ platform: ruby
6
+ authors:
7
+ - mynyml
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-06 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: nanotest
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: nanotest_extensions
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ description: Simple, minimalistic, standalone router meant to be used with pure rack applications.
46
+ email: mynyml@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files: []
52
+
53
+ files:
54
+ - .gitignore
55
+ - LICENSE
56
+ - Manifest
57
+ - README.md
58
+ - Rakefile
59
+ - TODO
60
+ - examples/rack_app.ru
61
+ - lib/simple_router.rb
62
+ - lib/simple_router/dsl.rb
63
+ - lib/simple_router/engines/simple_engine.rb
64
+ - lib/simple_router/routes.rb
65
+ - simple_router.gemspec
66
+ - test/engines/test_simple_engine.rb
67
+ - test/test_dsl.rb
68
+ - test/test_helper.rb
69
+ - test/test_routes.rb
70
+ - test/test_simple_router.rb
71
+ has_rdoc: true
72
+ homepage: http://github.com/mynyml/simple_router
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ version:
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ version:
92
+ requirements: []
93
+
94
+ rubyforge_project: simple_router
95
+ rubygems_version: 1.3.5
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Simple, minimalistic, standalone router meant to be used with pure rack applications
99
+ test_files: []
100
+