roda 0.9.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.
- checksums.yaml +7 -0
- data/CHANGELOG +3 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +709 -0
- data/Rakefile +124 -0
- data/lib/roda.rb +608 -0
- data/lib/roda/plugins/all_verbs.rb +48 -0
- data/lib/roda/plugins/default_headers.rb +50 -0
- data/lib/roda/plugins/error_handler.rb +69 -0
- data/lib/roda/plugins/flash.rb +62 -0
- data/lib/roda/plugins/h.rb +24 -0
- data/lib/roda/plugins/halt.rb +79 -0
- data/lib/roda/plugins/header_matchers.rb +57 -0
- data/lib/roda/plugins/hooks.rb +106 -0
- data/lib/roda/plugins/indifferent_params.rb +47 -0
- data/lib/roda/plugins/middleware.rb +88 -0
- data/lib/roda/plugins/multi_route.rb +77 -0
- data/lib/roda/plugins/not_found.rb +62 -0
- data/lib/roda/plugins/pass.rb +34 -0
- data/lib/roda/plugins/render.rb +217 -0
- data/lib/roda/plugins/streaming.rb +165 -0
- data/spec/composition_spec.rb +19 -0
- data/spec/env_spec.rb +11 -0
- data/spec/integration_spec.rb +63 -0
- data/spec/matchers_spec.rb +658 -0
- data/spec/module_spec.rb +29 -0
- data/spec/opts_spec.rb +42 -0
- data/spec/plugin/all_verbs_spec.rb +29 -0
- data/spec/plugin/default_headers_spec.rb +63 -0
- data/spec/plugin/error_handler_spec.rb +67 -0
- data/spec/plugin/flash_spec.rb +59 -0
- data/spec/plugin/h_spec.rb +13 -0
- data/spec/plugin/halt_spec.rb +62 -0
- data/spec/plugin/header_matchers_spec.rb +61 -0
- data/spec/plugin/hooks_spec.rb +97 -0
- data/spec/plugin/indifferent_params_spec.rb +13 -0
- data/spec/plugin/middleware_spec.rb +52 -0
- data/spec/plugin/multi_route_spec.rb +98 -0
- data/spec/plugin/not_found_spec.rb +99 -0
- data/spec/plugin/pass_spec.rb +23 -0
- data/spec/plugin/render_spec.rb +148 -0
- data/spec/plugin/streaming_spec.rb +52 -0
- data/spec/plugin_spec.rb +61 -0
- data/spec/redirect_spec.rb +24 -0
- data/spec/request_spec.rb +55 -0
- data/spec/response_spec.rb +131 -0
- data/spec/session_spec.rb +35 -0
- data/spec/spec_helper.rb +89 -0
- data/spec/version_spec.rb +8 -0
- metadata +148 -0
data/spec/plugin_spec.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "plugins" do
|
4
|
+
it "should be able to override class, instance, response, and request methods, and execute configure method" do
|
5
|
+
c = Module.new do
|
6
|
+
self::ClassMethods = Module.new do
|
7
|
+
def fix(str)
|
8
|
+
opts[:prefix] + str.strip
|
9
|
+
end
|
10
|
+
end
|
11
|
+
self::InstanceMethods = Module.new do
|
12
|
+
def fix(str)
|
13
|
+
super("a" + str)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
self::RequestMethods = Module.new do
|
17
|
+
def hello(&block)
|
18
|
+
on 'hello', &block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
self::ResponseMethods = Module.new do
|
22
|
+
def foobar
|
23
|
+
"Default "
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_dependencies(mod, prefix)
|
28
|
+
mod.send(:include, Module.new do
|
29
|
+
def fix(str)
|
30
|
+
self.class.fix(str)
|
31
|
+
end
|
32
|
+
end)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.configure(mod, prefix)
|
36
|
+
mod.opts[:prefix] = prefix
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
app(:bare) do
|
41
|
+
plugin c, "Foo "
|
42
|
+
|
43
|
+
route do |r|
|
44
|
+
r.hello do
|
45
|
+
fix(response.foobar)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
body('/hello').should == 'Foo aDefault'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should support registering plugins and loading them by symbol" do
|
54
|
+
Roda::RodaPlugins.register_plugin(:foo, Module.new{module self::InstanceMethods; def a; '1' end end})
|
55
|
+
app(:foo) do
|
56
|
+
a
|
57
|
+
end
|
58
|
+
|
59
|
+
body.should == '1'
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "redirects" do
|
4
|
+
it "should be immediately processed" do
|
5
|
+
app do |r|
|
6
|
+
r.on "about" do
|
7
|
+
r.redirect "/hello", 301
|
8
|
+
"Foo"
|
9
|
+
end
|
10
|
+
r.on do
|
11
|
+
r.redirect "/hello"
|
12
|
+
"Foo"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
status.should == 302
|
17
|
+
header('Location').should == '/hello'
|
18
|
+
body.should == ''
|
19
|
+
|
20
|
+
status("/about").should == 301
|
21
|
+
header('Location', "/about").should == '/hello'
|
22
|
+
body("/about").should == ''
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "request.full_path_info" do
|
4
|
+
it "should return the script name and path_info as a string" do
|
5
|
+
app do |r|
|
6
|
+
r.on "foo" do
|
7
|
+
"#{r.full_path_info}:#{r.script_name}:#{r.path_info}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
body("/foo/bar").should == "/foo/bar:/foo:/bar"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "request.halt" do
|
16
|
+
it "should return rack response as argument given it as argument" do
|
17
|
+
app do |r|
|
18
|
+
r.halt [200, {}, ['foo']]
|
19
|
+
end
|
20
|
+
|
21
|
+
body.should == "foo"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "request.scope" do
|
26
|
+
it "should return roda instance" do
|
27
|
+
app(:bare) do
|
28
|
+
attr_accessor :b
|
29
|
+
|
30
|
+
route do |r|
|
31
|
+
self.b = 'a'
|
32
|
+
request.scope.b
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
body.should == "a"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "request.inspect" do
|
41
|
+
it "should return information about request" do
|
42
|
+
app(:bare) do
|
43
|
+
def self.inspect
|
44
|
+
'Foo'
|
45
|
+
end
|
46
|
+
|
47
|
+
route do |r|
|
48
|
+
request.inspect
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
body('/a/b').should == "#<Foo::RodaRequest GET /a/b>"
|
53
|
+
body('REQUEST_METHOD'=>'POST').should == "#<Foo::RodaRequest POST />"
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "cookie handling" do
|
4
|
+
it "should set cookies on response" do
|
5
|
+
app do |r|
|
6
|
+
response.set_cookie("foo", "bar")
|
7
|
+
response.set_cookie("bar", "baz")
|
8
|
+
"Hello"
|
9
|
+
end
|
10
|
+
|
11
|
+
header('Set-Cookie').should == "foo=bar\nbar=baz"
|
12
|
+
body.should == 'Hello'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should delete cookies on response" do
|
16
|
+
app do |r|
|
17
|
+
response.set_cookie("foo", "bar")
|
18
|
+
response.delete_cookie("foo")
|
19
|
+
"Hello"
|
20
|
+
end
|
21
|
+
|
22
|
+
header('Set-Cookie').should =~ /foo=; (max-age=0; )?expires=Thu, 01[ -]Jan[ -]1970 00:00:00 (-0000|GMT)/
|
23
|
+
body.should == 'Hello'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "response #[] and #[]=" do
|
28
|
+
it "should get/set headers" do
|
29
|
+
app do |r|
|
30
|
+
response['foo'] = 'bar'
|
31
|
+
response['foo'] + response.headers['foo']
|
32
|
+
end
|
33
|
+
|
34
|
+
header('foo').should == "bar"
|
35
|
+
body.should == 'barbar'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "response #write" do
|
40
|
+
it "should add to body" do
|
41
|
+
app do |r|
|
42
|
+
response.write 'a'
|
43
|
+
response.write 'b'
|
44
|
+
end
|
45
|
+
|
46
|
+
body.should == 'ab'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "response #finish" do
|
51
|
+
it "should set status to 404 if body has not been written to" do
|
52
|
+
app do |r|
|
53
|
+
s, h, b = response.finish
|
54
|
+
"#{s}#{h['Content-Type']}#{b.length}"
|
55
|
+
end
|
56
|
+
|
57
|
+
body.should == '404text/html0'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set status to 200 if body has been written to" do
|
61
|
+
app do |r|
|
62
|
+
response.write 'a'
|
63
|
+
s, h, b = response.finish
|
64
|
+
response.write "#{s}#{h['Content-Type']}#{b.length}"
|
65
|
+
end
|
66
|
+
|
67
|
+
body.should == 'a200text/html1'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not overwrite existing status" do
|
71
|
+
app do |r|
|
72
|
+
response.status = 500
|
73
|
+
s, h, b = response.finish
|
74
|
+
"#{s}#{h['Content-Type']}#{b.length}"
|
75
|
+
end
|
76
|
+
|
77
|
+
body.should == '500text/html0'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "response #redirect" do
|
82
|
+
it "should set location and status" do
|
83
|
+
app do |r|
|
84
|
+
r.on 'a' do
|
85
|
+
response.redirect '/foo', 303
|
86
|
+
end
|
87
|
+
r.on do
|
88
|
+
response.redirect '/bar'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
status('/a').should == 303
|
93
|
+
status.should == 302
|
94
|
+
header('Location', '/a').should == '/foo'
|
95
|
+
header('Location').should == '/bar'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "response #empty?" do
|
100
|
+
it "should return whether the body is empty" do
|
101
|
+
app do |r|
|
102
|
+
r.on 'a' do
|
103
|
+
response['foo'] = response.empty?.to_s
|
104
|
+
end
|
105
|
+
r.on do
|
106
|
+
response.write 'a'
|
107
|
+
response['foo'] = response.empty?.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
header('foo', '/a').should == 'true'
|
112
|
+
header('foo').should == 'false'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "response #inspect" do
|
117
|
+
it "should return information about response" do
|
118
|
+
app(:bare) do
|
119
|
+
def self.inspect
|
120
|
+
'Foo'
|
121
|
+
end
|
122
|
+
|
123
|
+
route do |r|
|
124
|
+
response.status = 200
|
125
|
+
response.inspect
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
body.should == '#<Foo::RodaResponse 200 {"Content-Type"=>"text/html"} []>'
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "session handling" do
|
4
|
+
it "should give a warning if session variable is not available" do
|
5
|
+
app do |r|
|
6
|
+
begin
|
7
|
+
session
|
8
|
+
rescue Exception => e
|
9
|
+
e.message
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
body.should =~ /use Rack::Session::Cookie/
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return session if available" do
|
17
|
+
app(:bare) do
|
18
|
+
use Rack::Session::Cookie, :secret=>'1'
|
19
|
+
|
20
|
+
route do |r|
|
21
|
+
r.on do
|
22
|
+
(session[1] ||= 'a') << 'b'
|
23
|
+
session[1]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
_, h, b = req
|
29
|
+
b.join.should == 'ab'
|
30
|
+
_, h, b = req('HTTP_COOKIE'=>h['Set-Cookie'].sub("; path=/; HttpOnly", ''))
|
31
|
+
b.join.should == 'abb'
|
32
|
+
_, h, b = req('HTTP_COOKIE'=>h['Set-Cookie'].sub("; path=/; HttpOnly", ''))
|
33
|
+
b.join.should == 'abbb'
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
$:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
|
5
|
+
if ENV['COVERAGE']
|
6
|
+
require 'coverage'
|
7
|
+
require 'simplecov'
|
8
|
+
|
9
|
+
def SimpleCov.roda_coverage(opts = {})
|
10
|
+
start do
|
11
|
+
add_filter "/spec/"
|
12
|
+
add_group('Missing'){|src| src.covered_percent < 100}
|
13
|
+
add_group('Covered'){|src| src.covered_percent == 100}
|
14
|
+
yield self if block_given?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ENV.delete('COVERAGE')
|
19
|
+
SimpleCov.roda_coverage
|
20
|
+
end
|
21
|
+
|
22
|
+
require "roda"
|
23
|
+
require "stringio"
|
24
|
+
|
25
|
+
unless defined?(RSPEC_EXAMPLE_GROUP)
|
26
|
+
if defined?(RSpec)
|
27
|
+
require 'rspec/version'
|
28
|
+
if RSpec::Version::STRING >= '2.11.0'
|
29
|
+
RSpec.configure do |config|
|
30
|
+
config.expect_with :rspec do |c|
|
31
|
+
c.syntax = :should
|
32
|
+
end
|
33
|
+
config.mock_with :rspec do |c|
|
34
|
+
c.syntax = :should
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
RSPEC_EXAMPLE_GROUP = RSpec::Core::ExampleGroup
|
39
|
+
else
|
40
|
+
RSPEC_EXAMPLE_GROUP = Spec::Example::ExampleGroup
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class RSPEC_EXAMPLE_GROUP
|
45
|
+
def app(type=nil, &block)
|
46
|
+
case type
|
47
|
+
when :new
|
48
|
+
@app = _app{route(&block)}
|
49
|
+
when :bare
|
50
|
+
@app = _app(&block)
|
51
|
+
when Symbol
|
52
|
+
@app = _app do
|
53
|
+
plugin type
|
54
|
+
route(&block)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
@app ||= _app{route(&block)}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def req(path='/', env={})
|
62
|
+
if path.is_a?(Hash)
|
63
|
+
env = path
|
64
|
+
else
|
65
|
+
env['PATH_INFO'] = path
|
66
|
+
end
|
67
|
+
|
68
|
+
env = {"REQUEST_METHOD" => "GET", "PATH_INFO" => "/", "SCRIPT_NAME" => ""}.merge(env)
|
69
|
+
@app.call(env)
|
70
|
+
end
|
71
|
+
|
72
|
+
def status(path='/', env={})
|
73
|
+
req(path, env)[0]
|
74
|
+
end
|
75
|
+
|
76
|
+
def header(name, path='/', env={})
|
77
|
+
req(path, env)[1][name]
|
78
|
+
end
|
79
|
+
|
80
|
+
def body(path='/', env={})
|
81
|
+
req(path, env)[2].join
|
82
|
+
end
|
83
|
+
|
84
|
+
def _app(&block)
|
85
|
+
c = Class.new(Roda)
|
86
|
+
c.class_eval(&block)
|
87
|
+
c
|
88
|
+
end
|
89
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: roda
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Evans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sinatra-flash
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tilt
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Routing tree web framework, inspired by Sinatra and Cuba
|
70
|
+
email:
|
71
|
+
- code@jeremyevans.net
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- CHANGELOG
|
77
|
+
- MIT-LICENSE
|
78
|
+
- README.rdoc
|
79
|
+
- Rakefile
|
80
|
+
- lib/roda.rb
|
81
|
+
- lib/roda/plugins/all_verbs.rb
|
82
|
+
- lib/roda/plugins/default_headers.rb
|
83
|
+
- lib/roda/plugins/error_handler.rb
|
84
|
+
- lib/roda/plugins/flash.rb
|
85
|
+
- lib/roda/plugins/h.rb
|
86
|
+
- lib/roda/plugins/halt.rb
|
87
|
+
- lib/roda/plugins/header_matchers.rb
|
88
|
+
- lib/roda/plugins/hooks.rb
|
89
|
+
- lib/roda/plugins/indifferent_params.rb
|
90
|
+
- lib/roda/plugins/middleware.rb
|
91
|
+
- lib/roda/plugins/multi_route.rb
|
92
|
+
- lib/roda/plugins/not_found.rb
|
93
|
+
- lib/roda/plugins/pass.rb
|
94
|
+
- lib/roda/plugins/render.rb
|
95
|
+
- lib/roda/plugins/streaming.rb
|
96
|
+
- spec/composition_spec.rb
|
97
|
+
- spec/env_spec.rb
|
98
|
+
- spec/integration_spec.rb
|
99
|
+
- spec/matchers_spec.rb
|
100
|
+
- spec/module_spec.rb
|
101
|
+
- spec/opts_spec.rb
|
102
|
+
- spec/plugin/all_verbs_spec.rb
|
103
|
+
- spec/plugin/default_headers_spec.rb
|
104
|
+
- spec/plugin/error_handler_spec.rb
|
105
|
+
- spec/plugin/flash_spec.rb
|
106
|
+
- spec/plugin/h_spec.rb
|
107
|
+
- spec/plugin/halt_spec.rb
|
108
|
+
- spec/plugin/header_matchers_spec.rb
|
109
|
+
- spec/plugin/hooks_spec.rb
|
110
|
+
- spec/plugin/indifferent_params_spec.rb
|
111
|
+
- spec/plugin/middleware_spec.rb
|
112
|
+
- spec/plugin/multi_route_spec.rb
|
113
|
+
- spec/plugin/not_found_spec.rb
|
114
|
+
- spec/plugin/pass_spec.rb
|
115
|
+
- spec/plugin/render_spec.rb
|
116
|
+
- spec/plugin/streaming_spec.rb
|
117
|
+
- spec/plugin_spec.rb
|
118
|
+
- spec/redirect_spec.rb
|
119
|
+
- spec/request_spec.rb
|
120
|
+
- spec/response_spec.rb
|
121
|
+
- spec/session_spec.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
- spec/version_spec.rb
|
124
|
+
homepage: https://github.com/jeremyevans/roda
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
metadata: {}
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 2.2.2
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: Routing tree web framework
|
148
|
+
test_files: []
|