sinatra-unit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 0.1.0 / 2013-01-14
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,5 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/sinatra/unit.rb
data/README.txt ADDED
@@ -0,0 +1,84 @@
1
+ # sinatra-unit
2
+
3
+ * http://github.com/snarfmason/sinatra-unit
4
+
5
+ Testing harness for Sinatra to make proper unit tests/specs for actions.
6
+
7
+ Description
8
+ -----------
9
+
10
+ The idea is to instantiate your Sintra class and then execute the web request blocks on the instance
11
+ that you have created. It uses the `test_request` method (and shortcuts like `test_get`, `test_put`, etc)
12
+ to look up the block using the same route matching logic that Sinatra would use when receiving a request
13
+ from Rack.
14
+
15
+ Usage
16
+ -----
17
+
18
+ Basic usage:
19
+
20
+ @app = WebApp.new
21
+ response_body = @app.test_request(:get, '/')
22
+
23
+ of course you can do, params:
24
+
25
+ response_body = @app.test_request(:get, '/hi', :qsname => 'jon')
26
+
27
+ you can set the environment or session (if enabled) with a hash, before a request
28
+
29
+ @app.env = { :test => 'hello' }
30
+ @app.session = { :test => 'hello' }
31
+ response_body = @app.test_get '/showsession'
32
+
33
+ Currently the text of the response is returned from the `test_request` method. If you need access to headers or HTTP status you use the `response` object.
34
+
35
+ @app.response.status
36
+ @app.response.header['Content-Type']
37
+
38
+
39
+ Writing Tests
40
+ -------------
41
+
42
+ basic good route:
43
+
44
+ response_body = @app.test_request(:get, '/')
45
+ assert_equal "hello world", response_body
46
+ assert_equal 200, @app.response.status
47
+ assert_equal 'text/html', @app.response.header['Content-Type']
48
+
49
+ basic bad route:
50
+
51
+ assert_raise Sinatra::Unit::UnknownRouteError do
52
+ @app.test_get '/wrongroute'
53
+ end
54
+
55
+ basic redirect:
56
+
57
+ @app.test_get '/redirect'
58
+ assert @app.redirect?
59
+ assert_equal 302, @app.response.status
60
+
61
+ you can retrieve instance variables set in request blocks
62
+
63
+ # app
64
+ get '/showobject' do
65
+ @object = OpenStruct.new :foo => 1, :bar => 2, :baz => 3
66
+ "foo=#{@object.foo}&bar=#{@object.bar}&baz=#{@object.baz}"
67
+ end
68
+
69
+ # test
70
+ response_body = @app.test_get '/showobject'
71
+ assert_equal 'foo=1&bar=2&baz=3', response_body
72
+ assert_equal 1, @app.variables("object").foo
73
+
74
+ you can assert against session values
75
+
76
+ # app
77
+ post '/setsession' do
78
+ session[:test] = params[:test]
79
+ end
80
+
81
+ # test
82
+ assert_nil @app.session[:test]
83
+ @app.test_post '/setsession', :test => 'goodbye'
84
+ assert_equal 'goodbye', @app.session[:test]
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # -*- ruby -*-
2
+
3
+ require "rubygems"
4
+ require "hoe"
5
+
6
+ Hoe.plugin :isolate
7
+ # Hoe.plugin :rubyforge
8
+
9
+ Hoe.spec "sinatra-unit" do
10
+ dependency 'sinatra', '~> 1.3.3'
11
+
12
+ developer "Jonathan Mason", "jonathan.e.mason@gmail.com"
13
+
14
+ license "MIT"
15
+ end
16
+
17
+ # vim: syntax=ruby
@@ -0,0 +1,104 @@
1
+ require 'ostruct'
2
+
3
+ module Sinatra
4
+ class Unit
5
+ VERSION = '0.1.0'
6
+
7
+ class UnknownRouteError < StandardError
8
+ attr_accessor :method, :path, :params
9
+ def initialize(method, path, params)
10
+ self.method, self.path, self.params = method, path, params
11
+ message = "Could not resovle route #{method} #{path} with params #{params.inspect}"
12
+ super message
13
+ end
14
+ end
15
+
16
+ class SessionsDisabledError < StandardError ; end
17
+ end
18
+
19
+ class Base
20
+ def test_sessions_enabled?
21
+ return true if self.class.sessions?
22
+
23
+ used_middleware = self.class.instance_variable_get "@middleware"
24
+ used_middleware.each do |middleware|
25
+ return true if middleware.first == Rack::Session::Cookie
26
+ end
27
+
28
+ return false
29
+ end
30
+
31
+ # Normal sinatra session method just returns request.session which passes
32
+ # through to env['rack.session'] but I don't initialize the request object
33
+ # until just before the route lookkup, so I need to skip directly to env.
34
+ def session
35
+ raise Sinatra::Unit::SessionsDisabledError unless test_sessions_enabled?
36
+ env['rack.session'] ||= {}
37
+ end
38
+
39
+ # This doesn't exist in regular sinatra, but it's convenient for some tests
40
+ def session=(session)
41
+ raise Sinatra::Unit::SessionsDisabledError unless test_sessions_enabled?
42
+ env['rack.session'] = session
43
+ end
44
+
45
+ # test_request comes mostly from the guts of route! in Sinatra::Base
46
+ def test_request(method, path, params={})
47
+ @params = indifferent_params(params)
48
+
49
+ @request = Sinatra::Request.new(env)
50
+ @request.path_info = path # sinatra 1.3.3
51
+
52
+ @__protected_ivars = instance_variables + ["@__protected_ivars"]
53
+
54
+ # routes are stored by uppercase method, but I wanted the test interface
55
+ # to accept :get or 'get' as well as 'GET'
56
+ test_request_internal self.class, method.to_s.upcase
57
+ end
58
+
59
+ def variables(name)
60
+ name = "@#{name.to_s}"
61
+ instance_variable_get(name) unless @__protected_ivars.include?(name)
62
+ end
63
+
64
+ # expects @request and @params to be set
65
+ # Don't call this directly, but I don't believe in private methods
66
+ def test_request_internal(route_holder, method)
67
+ raise Sinatra::Unit::UnknownRouteError.new(method,@request.path_info,@params) unless route_holder.respond_to?(:routes)
68
+
69
+ if route_holder.routes.has_key? method
70
+ routes = route_holder.routes[method]
71
+ routes.each do |pattern, keys, conditions, block|
72
+ process_route(pattern, keys, conditions) do |*args|
73
+ return catch(:halt) { block[*args] }
74
+ end
75
+ end
76
+ end
77
+
78
+ test_request_internal(route_holder.superclass, method)
79
+ end
80
+
81
+ %w(get post put delete head).each do |method|
82
+ eval <<-CODE
83
+ def test_#{method}(path, params={})
84
+ test_request('#{method}', path, params)
85
+ end
86
+ CODE
87
+ end
88
+
89
+ # Sinatra makes new do a bunch of stuff with rack middleware wrappers
90
+ # that are useful if you're actually running the app, but provides
91
+ # new! for regular instantiation. I'm just re-standardizing names
92
+ class << self
93
+ alias new_with_rack_wrappers new
94
+ end
95
+
96
+ def self.new
97
+ app = new!
98
+ app.env ||= {}
99
+ app.response = Sinatra::Response.new
100
+ app
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,26 @@
1
+ require 'no_sessions_app'
2
+ require 'sinatra/unit'
3
+
4
+ require 'test/unit'
5
+
6
+ class TestNoSessionsApp < Test::Unit::TestCase
7
+ def setup
8
+ @app = NoSessionsApp.new
9
+ end
10
+
11
+ def test_session_show
12
+ assert_raises Sinatra::Unit::SessionsDisabledError do
13
+ @app.session = { :test => 'hello' }
14
+ response_body = @app.test_get '/showsession'
15
+ assert_equal 'session[test] hello', response_body
16
+ end
17
+ end
18
+
19
+ def test_session_set
20
+ assert_raises Sinatra::Unit::SessionsDisabledError do
21
+ assert_nil @app.session[:test]
22
+ @app.test_post '/setsession', :test => 'goodbye'
23
+ assert_equal 'goodbye', @app.session[:test]
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ require 'rack_sessions_app'
2
+ require 'sinatra/unit'
3
+
4
+ require 'test/unit'
5
+
6
+ class TestRackSessionsApp < Test::Unit::TestCase
7
+ def setup
8
+ @app = RackSessionsApp.new
9
+ end
10
+
11
+ def test_session_show
12
+ @app.session = { :test => 'hello' }
13
+ response_body = @app.test_get '/showsession'
14
+ assert_equal 'session[test] hello', response_body
15
+ end
16
+
17
+ def test_session_set
18
+ assert_nil @app.session[:test]
19
+ @app.test_post '/setsession', :test => 'goodbye'
20
+ assert_equal 'goodbye', @app.session[:test]
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ require 'web_app'
2
+ require 'sinatra/unit'
3
+ require 'test/unit'
4
+
5
+ class TestUnknownRouteError < Test::Unit::TestCase
6
+ def test_unknown_route_exception_details
7
+ error = nil
8
+ begin
9
+ WebApp.new.test_get '/wrongroute', :wrong_param => 'foobar'
10
+ rescue => e
11
+ error = e
12
+ end
13
+
14
+ assert_not_nil error
15
+ assert_equal 'GET', error.method
16
+ assert_equal '/wrongroute', error.path
17
+ assert_equal 'foobar', error.params[:wrong_param]
18
+ assert_match %r{GET.*/wrongroute.*wrong_param.*foobar}, error.message
19
+ end
20
+ end
21
+
@@ -0,0 +1,105 @@
1
+ require 'web_app'
2
+ require 'sinatra/unit'
3
+
4
+ require 'test/unit'
5
+
6
+ class TestWebApp < Test::Unit::TestCase
7
+ def setup
8
+ @app = WebApp.new
9
+ end
10
+
11
+ def test_returns_hello_world_on_index
12
+ response_body = @app.test_request(:get, '/')
13
+ assert_equal "hello world", response_body
14
+ assert_equal 200, @app.response.status
15
+ assert_equal 'text/html', @app.response.header['Content-Type']
16
+ end
17
+
18
+ def test_returns_goodbye_on_bye
19
+ response_body = @app.test_request(:get, '/bye')
20
+ assert_equal "goodbye", response_body
21
+ end
22
+
23
+ def test_has_hello_name
24
+ response_body = @app.test_request(:get, '/hello/jon')
25
+ assert_equal "hello jon", response_body
26
+ end
27
+
28
+ def test_returns_for_hi_with_param
29
+ response_body = @app.test_request(:get, '/hi', :qsname => 'jon')
30
+ assert_equal "hi jon", response_body
31
+ end
32
+
33
+ def test_work_with_get_wrapped_method
34
+ response_body = @app.test_get '/'
35
+ assert_equal "hello world", response_body
36
+ end
37
+
38
+ def test_raises_an_exception_for_unknown_route
39
+ assert_raise Sinatra::Unit::UnknownRouteError do
40
+ @app.test_get '/wrongroute'
41
+ end
42
+ end
43
+
44
+ def test_works_with_post_data
45
+ response_body = @app.test_post '/goodnight', :name => 'jon'
46
+ assert_equal 'post goodnight jon', response_body
47
+ end
48
+
49
+ def test_works_with_pu
50
+ response_body = @app.test_put '/goodnight', :name => 'jon'
51
+ assert_equal 'put goodnight jon', response_body
52
+ end
53
+
54
+ def test_works_with_env
55
+ @app.env = { :test => 'hello' }
56
+ response_body = @app.test_post '/showenv'
57
+ assert_equal 'env[test] hello', response_body
58
+ end
59
+
60
+ def test_session_show
61
+ @app.session = { :test => 'hello' }
62
+ response_body = @app.test_get '/showsession'
63
+ assert_equal 'session[test] hello', response_body
64
+ end
65
+
66
+ def test_session_set
67
+ assert_nil @app.session[:test]
68
+ @app.test_post '/setsession', :test => 'goodbye'
69
+ assert_equal 'goodbye', @app.session[:test]
70
+ end
71
+
72
+ def test_instance_variable_retrieval
73
+ response_body = @app.test_get '/showobject'
74
+ assert_equal 'foo=1&bar=2&baz=3', response_body
75
+ assert_equal 1, @app.variables("object").foo
76
+ end
77
+
78
+ def test_only_retrieve_instance_variables_set_in_the_block
79
+ response_body = @app.test_get '/showobject'
80
+ assert_nil @app.variables("template_cache")
81
+ end
82
+
83
+ def test_do_not_retrieve_protected_instance_variables
84
+ response_body = @app.test_get '/showobject'
85
+ assert_nil @app.variables("__protected_ivars")
86
+ end
87
+
88
+ def test_redirect_to_index
89
+ @app.test_get '/redirect'
90
+ assert @app.redirect?
91
+ assert_equal 302, @app.response.status
92
+ end
93
+
94
+ def test_two_requests
95
+ response_body = @app.test_request(:get, '/')
96
+ assert_equal "hello world", response_body
97
+ assert_equal 200, @app.response.status
98
+ assert_equal 'text/html', @app.response.header['Content-Type']
99
+
100
+ @app.test_get '/redirect'
101
+ assert @app.redirect?
102
+ assert_equal 302, @app.response.status
103
+ end
104
+
105
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-unit
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Jonathan Mason
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-04-26 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sinatra
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 29
29
+ segments:
30
+ - 1
31
+ - 3
32
+ - 3
33
+ version: 1.3.3
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rdoc
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 19
45
+ segments:
46
+ - 3
47
+ - 10
48
+ version: "3.10"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: hoe
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 13
60
+ segments:
61
+ - 3
62
+ - 5
63
+ version: "3.5"
64
+ type: :development
65
+ version_requirements: *id003
66
+ description: ""
67
+ email:
68
+ - jonathan.e.mason@gmail.com
69
+ executables: []
70
+
71
+ extensions: []
72
+
73
+ extra_rdoc_files:
74
+ - History.txt
75
+ - Manifest.txt
76
+ - README.txt
77
+ files:
78
+ - History.txt
79
+ - Manifest.txt
80
+ - README.txt
81
+ - Rakefile
82
+ - lib/sinatra/unit.rb
83
+ - test/unit/test_no_sessions_app.rb
84
+ - test/unit/test_rack_session_app.rb
85
+ - test/unit/test_unknown_route_error.rb
86
+ - test/unit/test_web_app.rb
87
+ - .gemtest
88
+ homepage: http://github.com/snarfmason/sinatra-unit
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options:
93
+ - --main
94
+ - README.txt
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ requirements: []
116
+
117
+ rubyforge_project: sinatra-unit
118
+ rubygems_version: 1.8.25
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: ""
122
+ test_files:
123
+ - test/unit/test_no_sessions_app.rb
124
+ - test/unit/test_rack_session_app.rb
125
+ - test/unit/test_unknown_route_error.rb
126
+ - test/unit/test_web_app.rb