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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +3 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +709 -0
  5. data/Rakefile +124 -0
  6. data/lib/roda.rb +608 -0
  7. data/lib/roda/plugins/all_verbs.rb +48 -0
  8. data/lib/roda/plugins/default_headers.rb +50 -0
  9. data/lib/roda/plugins/error_handler.rb +69 -0
  10. data/lib/roda/plugins/flash.rb +62 -0
  11. data/lib/roda/plugins/h.rb +24 -0
  12. data/lib/roda/plugins/halt.rb +79 -0
  13. data/lib/roda/plugins/header_matchers.rb +57 -0
  14. data/lib/roda/plugins/hooks.rb +106 -0
  15. data/lib/roda/plugins/indifferent_params.rb +47 -0
  16. data/lib/roda/plugins/middleware.rb +88 -0
  17. data/lib/roda/plugins/multi_route.rb +77 -0
  18. data/lib/roda/plugins/not_found.rb +62 -0
  19. data/lib/roda/plugins/pass.rb +34 -0
  20. data/lib/roda/plugins/render.rb +217 -0
  21. data/lib/roda/plugins/streaming.rb +165 -0
  22. data/spec/composition_spec.rb +19 -0
  23. data/spec/env_spec.rb +11 -0
  24. data/spec/integration_spec.rb +63 -0
  25. data/spec/matchers_spec.rb +658 -0
  26. data/spec/module_spec.rb +29 -0
  27. data/spec/opts_spec.rb +42 -0
  28. data/spec/plugin/all_verbs_spec.rb +29 -0
  29. data/spec/plugin/default_headers_spec.rb +63 -0
  30. data/spec/plugin/error_handler_spec.rb +67 -0
  31. data/spec/plugin/flash_spec.rb +59 -0
  32. data/spec/plugin/h_spec.rb +13 -0
  33. data/spec/plugin/halt_spec.rb +62 -0
  34. data/spec/plugin/header_matchers_spec.rb +61 -0
  35. data/spec/plugin/hooks_spec.rb +97 -0
  36. data/spec/plugin/indifferent_params_spec.rb +13 -0
  37. data/spec/plugin/middleware_spec.rb +52 -0
  38. data/spec/plugin/multi_route_spec.rb +98 -0
  39. data/spec/plugin/not_found_spec.rb +99 -0
  40. data/spec/plugin/pass_spec.rb +23 -0
  41. data/spec/plugin/render_spec.rb +148 -0
  42. data/spec/plugin/streaming_spec.rb +52 -0
  43. data/spec/plugin_spec.rb +61 -0
  44. data/spec/redirect_spec.rb +24 -0
  45. data/spec/request_spec.rb +55 -0
  46. data/spec/response_spec.rb +131 -0
  47. data/spec/session_spec.rb +35 -0
  48. data/spec/spec_helper.rb +89 -0
  49. data/spec/version_spec.rb +8 -0
  50. metadata +148 -0
@@ -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
@@ -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
@@ -0,0 +1,8 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ describe "Roda::RodaVersion" do
4
+ it "should be a string in x.y.z integer format" do
5
+ Roda::RodaVersion.should =~ /\A\d+\.\d+\.\d+\z/
6
+ end
7
+ end
8
+
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: []