lookout-rack 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d174e7a91e29167fea81278368ad27380e8e81d6
4
+ data.tar.gz: 867a6cddfb2e05f3db2c615b84df1a870fee8342
5
+ SHA512:
6
+ metadata.gz: 1030b3fdd660bcd4585f3e54ea8e1116392bcfa7addc79954e87fe98667cde69437acd8cf4048943b62b1e373add7ebb4c48fab6c285aa262ff964aa3d546a00
7
+ data.tar.gz: 46742114d3ecf302a35387cad7053d6359a2b4c773d5c876b421836bc2a6788720ee6d57c1d29c16e6bcd5813813049600e54207226735ae34766e6f32f1a51f
data/fixtures/app.rb ADDED
@@ -0,0 +1,102 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'sinatra/base'
4
+
5
+ module Lookout module Rack end end
6
+
7
+ class Lookout::Rack::TestApp < Sinatra::Base
8
+ get '/' do
9
+ 'GET: %p' % params
10
+ end
11
+
12
+ post '/' do
13
+ 'POST: %p' % params
14
+ end
15
+
16
+ get '/redirected' do
17
+ redirect '/target'
18
+ end
19
+
20
+ get '/target' do
21
+ 'you have been successfully redirected to target'
22
+ end
23
+
24
+ get '/cookies/show' do
25
+ request.cookies.inspect
26
+ end
27
+
28
+ get '/cookies/set' do
29
+ response.set_cookie 'value',
30
+ :value => params['value'],
31
+ :path => '/cookies',
32
+ :expires => Time.now + 60
33
+
34
+ 'cookie has been set'
35
+ end
36
+
37
+ get '/cookies/expired' do
38
+ response.set_cookie 'value',
39
+ :value => params['value'],
40
+ :path => '/cookies',
41
+ :expires => Time.now - 60
42
+
43
+ 'expired cookie have been set'
44
+ end
45
+
46
+ get '/no-cookies/show' do
47
+ request.cookies.inspect
48
+ end
49
+
50
+ get '/cookies/delete' do
51
+ response.delete_cookie 'value'
52
+ end
53
+
54
+ get '/COOKIES/show' do
55
+ request.cookies.inspect
56
+ end
57
+
58
+ get '/cookies/set-uppercase' do
59
+ response.set_cookie 'VALUE',
60
+ :value => params['value'],
61
+ :path => '/cookies',
62
+ :expires => Time.now + 60
63
+
64
+ 'cookie has been set'
65
+ end
66
+
67
+ get '/cookies/set-simple' do
68
+ response.set_cookie 'simple', params['value']
69
+
70
+ 'cookie has been set'
71
+ end
72
+
73
+ get '/cookies/set-secure' do
74
+ response.set_cookie 'value',
75
+ :value => params['value'],
76
+ :secure => true
77
+
78
+ 'cookie has been set'
79
+ end
80
+
81
+ get '/cookies/subdomain' do
82
+ response.set_cookie 'count',
83
+ :value => ((request.cookies['count'].to_i or 0) + 1).to_s,
84
+ :domain => '.example.com'
85
+
86
+ 'cookie has been set'
87
+ end
88
+
89
+ get '/cookies/set-multiple' do
90
+ response.set_cookie 'value', :value => '1'
91
+ response.set_cookie 'other', :value => '2'
92
+
93
+ 'cookies have been set'
94
+ end
95
+
96
+ get '/cookies/count' do
97
+ response.set_cookie 'count',
98
+ :value => ((request.cookies['count'].to_i or 0) + 1).to_s
99
+
100
+ 'cookie has been set'
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require File.expand_path('../app', __FILE__)
4
+ use Rack::Lint
5
+ run Lookout::Rack::TestApp
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Namespace for [Lookout](http://disu.se/software/lookout/). The bulk of the
4
+ # library is in {Lookout::Rack::Session}.
5
+ module Lookout end
6
+
7
+ # [Rack](http://rack.rubyforge.org/) interface for
8
+ # [Lookout](http://disu.se/software/lookout/).
9
+ module Lookout::Rack
10
+ # The default host/URI to use for {Session#dispatch requests} and cookies.
11
+ DefaultHost = 'example.org'
12
+
13
+ # Base class for errors raised from Lookout::Rack.
14
+ Error = Class.new(StandardError)
15
+
16
+ # Error raised when a redirect is tried when none has been specified.
17
+ RedirectError = Class.new(Error)
18
+
19
+ # Error raised when a request hasn’t been made yet.
20
+ RequestError = Class.new(Error)
21
+
22
+ # Error raised when a response hasn’t been received yet.
23
+ ResponseError = Class.new(Error)
24
+
25
+ load File.expand_path('../lookout-rack-1.0/version.rb', __FILE__)
26
+ Version.load
27
+ end
28
+
29
+ class Lookout::Expectations::Context
30
+ include Lookout::Rack::Methods
31
+ end
32
+
33
+ class Lookout::Expect::Object::Context
34
+ include Lookout::Rack::Methods
35
+ end
@@ -0,0 +1,79 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Rack::Cookie
4
+ include Comparable
5
+
6
+ def initialize(header, uri = nil, default_host = Lookout::Rack::DefaultHost)
7
+ @default_host = default_host
8
+ uri ||= default_uri
9
+
10
+ @cookie, options = header.split(/[;,] */n, 2)
11
+
12
+ @name, @value = Rack::Utils.parse_query(@cookie, ';').to_a.first
13
+
14
+ @options = Hash[Rack::Utils.parse_query(options, ';').map{ |k, v| [k.downcase, v] }]
15
+ @options['domain'] ||= uri.host || default_host
16
+ @options['path'] ||= uri.path.sub(%r{/[^/]*\z}, '')
17
+ end
18
+
19
+ def empty?
20
+ @value.nil? or @value.empty?
21
+ end
22
+
23
+ def valid?(uri)
24
+ uri ||= default_uri
25
+ uri.host ||= @default_host
26
+
27
+ real_domain = domain.start_with?('.') ? domain[1..-1] : domain
28
+ secure? uri and
29
+ uri.host.downcase.end_with? real_domain.downcase and
30
+ uri.path.start_with? path
31
+ end
32
+
33
+ def matches?(uri)
34
+ valid? uri and not expired?
35
+ end
36
+
37
+ def eql?(other)
38
+ self.class === other and self == other
39
+ end
40
+
41
+ def <=>(other)
42
+ [name.downcase, path, domain.reverse] <=>
43
+ [other.name.downcase, other.path, other.domain.reverse]
44
+ end
45
+
46
+ def hash
47
+ name.downcase.hash ^ path.hash ^ domain.hash
48
+ end
49
+
50
+ def to_s
51
+ @cookie
52
+ end
53
+
54
+ attr_reader :name
55
+
56
+ protected
57
+
58
+ def domain
59
+ @options['domain']
60
+ end
61
+
62
+ def path
63
+ @options['path'].strip
64
+ end
65
+
66
+ private
67
+
68
+ def default_uri
69
+ URI('//%s/' % @default_host)
70
+ end
71
+
72
+ def secure?(uri)
73
+ not @options.include? 'secure' or uri.scheme == 'https'
74
+ end
75
+
76
+ def expired?
77
+ @options['expires'] and Time.parse(@options['expires']) < Time.now
78
+ end
79
+ end
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Lookout::Rack::Cookies
4
+ def initialize(default_host = Lookout::Rack::DefaultHost)
5
+ @default_host = default_host
6
+ @cookies = {}
7
+ end
8
+
9
+ def merge!(headers, uri = nil)
10
+ headers.split("\n").reject{ |c| c.empty? }.each do |header|
11
+ cookie = Lookout::Rack::Cookie.new(header, uri, @default_host)
12
+ @cookies[cookie] = cookie if cookie.valid? uri
13
+ end
14
+ self
15
+ end
16
+
17
+ def for(uri)
18
+ @cookies.values.select{ |c| c.matches? uri }.sort.
19
+ reduce({}){ |h, c| h[c.name] = c; h }.values.join(';')
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Methods added to [Lookout](http://disu.se/software/lookout)’s expectations
4
+ # and expect block context’s.
5
+ module Lookout::Rack::Methods
6
+ private
7
+
8
+ # @return [Session] A new session object that wraps the global Rack app found
9
+ # in the file “fixtures/config.ru” or “config.ru” in the top-level project
10
+ # directory.
11
+ def session
12
+ @app ||= begin
13
+ Rack::Builder.parse_file('fixtures/config.ru')
14
+ rescue Errno::ENOENT
15
+ Rack::Builder.parse_file('config.ru')
16
+ end[0]
17
+ Lookout::Rack::Session.new(@app)
18
+ end
19
+ end
@@ -0,0 +1,116 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # A [Rack](http://rack.rubyforge.org/) session for use with
4
+ # [Lookout](http://disu.se/software/lookout/). Given a Rack “app”, it’ll allow
5
+ # you to make {#get}, {#post}, {#put}, and {#delete} requests (and actually
6
+ # {#dispatch} arbitrary requests, if you desire), check the sent {#request},
7
+ # check the received {#response}, follow {#redirect!}s, add {#cookie}s, and
8
+ # {#clear} cookies.
9
+ class Lookout::Rack::Session
10
+ # Sets up a new session for APP. You’ll most likely not call this yourself,
11
+ # leaving it up to {Methods#session} to do so.
12
+ #
13
+ # @param [#call] app
14
+ def initialize(app)
15
+ @app = app
16
+ @request = nil
17
+ @response = nil
18
+ clear
19
+ end
20
+
21
+ # Dispatches a GET request.
22
+ # @param (see #dispatch)
23
+ # @return (see #dispatch)
24
+ def get(uri, params = {}, env = {})
25
+ dispatch('GET', uri, params, env)
26
+ end
27
+
28
+ # Dispatches a POST request.
29
+ # @param (see #dispatch)
30
+ # @return (see #dispatch)
31
+ def post(uri, params = {}, env = {})
32
+ dispatch('POST', uri, params, env)
33
+ end
34
+
35
+ # Dispatches a PUT request.
36
+ # @param (see #dispatch)
37
+ # @return (see #dispatch)
38
+ def put(uri, params = {}, env = {})
39
+ dispatch('PUT', uri, params, env)
40
+ end
41
+
42
+ # Dispatches a DELETE request.
43
+ # @param (see #dispatch)
44
+ # @return (see #dispatch)
45
+ def delete(uri, params = {}, env = {})
46
+ dispatch('DELETE', uri, params, env)
47
+ end
48
+
49
+ # Dispatches a METHOD {#request} to URI with PARAMS in ENV and gets its
50
+ # {#response}, storing any returned {#cookie}s. For more information on ENV,
51
+ # see
52
+ # [Rack::MockRequest](http://rack.rubyforge.org/doc/classes/Rack/MockRequest.html).
53
+ #
54
+ # @param [String] method
55
+ # @param [String] uri
56
+ # @param [Hash] params
57
+ # @param [Hash] env
58
+ # @return [self]
59
+ def dispatch(method, uri = '', params = {}, env = {})
60
+ uri = URI(uri)
61
+ uri.host ||= Lookout::Rack::DefaultHost
62
+ env = Rack::MockRequest.env_for(uri.to_s, env.merge(:method => method, :params => params))
63
+ env['HTTP_COOKIE'] ||= @cookies.for(uri)
64
+ @request = Rack::Request.new(env)
65
+ errors = env['rack.errors']
66
+ status, headers, body = *(env[:lint] ? Rack::Lint.new(@app) : @app).call(env)
67
+ @response = Rack::MockResponse.new(status, headers, body, errors.flush)
68
+ body.close if body.respond_to?(:close)
69
+ @cookies.merge! @response.headers['Set-Cookie'], uri if @response.headers['Set-Cookie']
70
+ self
71
+ end
72
+
73
+ # @return [Rack::Request] The Rack request that was most recently sent during
74
+ # this session
75
+ # @raise [RequestError] If no request has been sent yet
76
+ def request
77
+ @request or raise Lookout::Rack::RequestError, 'no request has been sent yet'
78
+ end
79
+
80
+ # @return [Rack::MockResponse] The Rack response that was most recently
81
+ # received during this session
82
+ # @raise [RequestError] If no response has been received yet
83
+ def response
84
+ @response or raise Lookout::Rack::ResponseError, 'no response has been received yet'
85
+ end
86
+
87
+ # Redirects to the most recent response’s redirected location by performing a
88
+ # {#get} request to the “Location” header of the response.
89
+ #
90
+ # @raise [RequestError] If no response has been received yet
91
+ # @raise [RedirectError] If the last response wasn’t a redirect
92
+ # @return [self]
93
+ def redirect!
94
+ response.redirect? or
95
+ raise Lookout::Rack::RedirectError, 'most recent response was not a redirect'
96
+ get(response['Location'])
97
+ end
98
+
99
+ # Sets COOKIE, being a newline-, comma-, and semicolon-separated list of
100
+ # `KEY=VALUE` pairs, for URI, or the {Lookout::Rack::DefaultHost default
101
+ # URI}, in the session.
102
+ # @param [String] cookie
103
+ # @param [String, nil] uri
104
+ # @return [self]
105
+ def cookie(cookie, uri = nil)
106
+ @cookies.merge! cookie, uri
107
+ self
108
+ end
109
+
110
+ # Clears all cookies from the session.
111
+ # @return [self]
112
+ def clear
113
+ @cookies = Lookout::Rack::Cookies.new
114
+ self
115
+ end
116
+ end
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'inventory-1.0'
4
+
5
+ module Lookout::Rack
6
+ Version = Inventory.new(1, 0, 0){
7
+ def dependencies
8
+ super + Inventory::Dependencies.new{
9
+ development 'inventory-rake', 1, 4, 0
10
+ development 'inventory-rake-tasks-yard', 1, 3, 0
11
+ development 'lookout-rake', 3, 0, 0
12
+ development 'sinatra', 1, 0, 0
13
+ development 'yard', 0, 8, 0
14
+ development 'yard-heuristics', 1, 1, 0
15
+ runtime 'lookout', 3, 0, 0
16
+ runtime 'rack', 1, 0, 0, :feature => 'rack'
17
+ }
18
+ end
19
+
20
+ def requires
21
+ %w[time
22
+ uri]
23
+ end
24
+
25
+ def package_libs
26
+ %w[cookie.rb
27
+ cookies.rb
28
+ methods.rb
29
+ session.rb]
30
+ end
31
+
32
+ def additional_files
33
+ %w[fixtures/app.rb
34
+ fixtures/config.ru]
35
+ end
36
+ }
37
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Expectations do
4
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Expectations do
4
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Expectations do
4
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Expectations do
4
+ end
@@ -0,0 +1,169 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Expectations do
4
+ expect 'GET' do
5
+ session.get('/').request.env['REQUEST_METHOD']
6
+ end
7
+
8
+ expect 200 do
9
+ session.get('/').response.status
10
+ end
11
+
12
+ expect result.redirect? do
13
+ session.get('/redirected').response
14
+ end
15
+
16
+ expect result.not.redirect? do
17
+ session.get('/redirected').redirect!.response
18
+ end
19
+
20
+ expect 'you have been successfully redirected to target' do
21
+ session.get('/redirected').redirect!.response.body
22
+ end
23
+
24
+ expect({}) do
25
+ session.get('/redirected').redirect!.request.GET
26
+ end
27
+
28
+ expect Lookout::Rack::ResponseError do
29
+ session.redirect!
30
+ end
31
+
32
+ expect Lookout::Rack::RedirectError do
33
+ session.get('/').redirect!
34
+ end
35
+
36
+ expect({}) do
37
+ session.get('/cookies/show').request.cookies
38
+ end
39
+
40
+ expect 'value' => '1' do
41
+ session.get('/cookies/set', 'value' => '1').get('/cookies/show').request.cookies
42
+ end
43
+
44
+ expect 'value' => '1' do
45
+ session.get('/cookies/set', 'value' => '1').get('/cookies/show').get('/cookies/show').request.cookies
46
+ end
47
+
48
+ expect({}) do
49
+ session.get('/cookies/expired', 'value' => '1').get('/cookies/show').request.cookies
50
+ end
51
+
52
+ expect 'value' => '1' do
53
+ session.get('http://example.org/cookies/set', 'value' => '1').get('http://example.org/cookies/show').request.cookies
54
+ end
55
+
56
+ expect({}) do
57
+ session.get('http://example.org/cookies/set', 'value' => '1').get('http://example.net/cookies/show').request.cookies
58
+ end
59
+
60
+ expect({}) do
61
+ session.get('/cookies/set', 'value' => '1').get('/no-cookies/show').request.cookies
62
+ end
63
+
64
+ expect({}) do
65
+ session.get('/cookies/set', 'value' => '1').get('/cookies/delete').get('/cookies/show').request.cookies
66
+ end
67
+
68
+ expect 'value' => '1' do
69
+ session.get('http://example.com/cookies/set', 'value' => '1').get('http://EXAMPLE.COM/cookies/show').request.cookies
70
+ end
71
+
72
+ expect({}) do
73
+ session.get('/cookies/set', 'value' => '1').get('/COOKIES/show').request.cookies
74
+ end
75
+
76
+ expect 'value' => 'sub' do
77
+ session.
78
+ get('http://example.com/cookies/set', 'value' => 'domain').
79
+ get('http://sub.example.com/cookies/set', 'value' => 'sub').
80
+ get('http://sub.example.com/cookies/show').request.cookies
81
+ end
82
+
83
+ expect 'value' => 'domain' do
84
+ session.
85
+ get('http://example.com/cookies/set', 'value' => 'domain').
86
+ get('http://sub.example.com/cookies/set', 'value' => 'sub').
87
+ get('http://example.com/cookies/show').request.cookies
88
+ end
89
+
90
+ expect 'VALUE' => 'UPPERCASE' do
91
+ session.
92
+ get('/cookies/set', 'value' => 'lowercase').
93
+ get('/cookies/set-uppercase', 'value' => 'UPPERCASE').
94
+ get('/cookies/show').request.cookies
95
+ end
96
+
97
+ expect 'simple' => 'cookie' do
98
+ session.
99
+ get('http://example.com/cookies/set-simple', 'value' => 'cookie').
100
+ get('http://example.com/cookies/show').request.cookies
101
+ end
102
+
103
+ expect({}) do
104
+ session.
105
+ get('http://example.com/cookies/set-simple', 'value' => 'cookie').
106
+ get('http://example.com/cookies/show').
107
+ get('http://example.net/cookies/show').request.cookies
108
+ end
109
+
110
+ expect({}) do
111
+ session.get('/cookies/set-simple', 'value' => '1').get('/not-cookies/show').request.cookies
112
+ end
113
+
114
+ expect({}) do
115
+ session.
116
+ get('https://example.com/cookies/set-secure', 'value' => '1').
117
+ get('http://example.com/cookies/show').request.cookies
118
+ end
119
+
120
+ expect 'value' => '1' do
121
+ session.
122
+ get('https://example.com/cookies/set-secure', 'value' => '1').
123
+ get('https://example.com/cookies/show').request.cookies
124
+ end
125
+
126
+ expect 'value' => 'com' do
127
+ session.
128
+ get('http://example.com/cookies/set', 'value' => 'com').
129
+ get('http://example.net/cookies/set', 'value' => 'net').
130
+ get('http://example.com/cookies/show').request.cookies
131
+ end
132
+
133
+ expect 'count' => '2' do
134
+ session.
135
+ get('http://example.com/cookies/subdomain').
136
+ get('http://example.com/cookies/subdomain').
137
+ get('http://foo.example.com/cookies/subdomain').request.cookies
138
+ end
139
+
140
+ expect({}) do
141
+ session.get('/cookies/set', 'value' => '1').clear.get('/cookies/show').request.cookies
142
+ end
143
+
144
+ expect 'value' => '1' do
145
+ session.cookie('value=1').get('/cookies/show').request.cookies
146
+ end
147
+
148
+ expect 'value' => '1', 'other' => '2' do
149
+ session.cookie("value=1\n\nother=2").get('/cookies/show').request.cookies
150
+ end
151
+
152
+ expect 'value' => '1', 'other' => '2' do
153
+ session.get('/cookies/set-multiple').get('/cookies/show').request.cookies
154
+ end
155
+
156
+ expect 'first' => {'value' => '1'}, 'second' => {} do
157
+ {
158
+ 'first' => session.get('/cookies/set', 'value' => '1').get('/cookies/show').request.cookies,
159
+ 'second' => session.get('/cookies/show').request.cookies
160
+ }
161
+ end
162
+
163
+ expect 'count' => '1' do
164
+ session.
165
+ get('http://example.org/cookies/count').
166
+ get('http://www.example.org/cookies/count').
167
+ get('http://example.org/cookies/show').request.cookies
168
+ end
169
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ Expectations do
4
+ end
metadata ADDED
@@ -0,0 +1,316 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lookout-rack
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nikolai Weibull
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: inventory
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: inventory-rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: inventory-rake-tasks-yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: lookout-rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sinatra
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.8.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard-heuristics
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.1'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: lookout
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rack
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: '1.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: '1.0'
139
+ description: |2
140
+ Lookout-Rack
141
+
142
+ Lookout-Rack provides easy interaction with Rack¹ from Lookout². It provides
143
+ you with a session connected to your Rack application through which you can
144
+ make requests, check responses, follow redirects and set, inspect, and clear
145
+ cookies.
146
+
147
+ ¹ See http://rack.rubyforge.org/
148
+ ² See http://disu.se/software/lookout/
149
+
150
+ § Installation
151
+
152
+ Install Lookout-Rack with
153
+
154
+ % gem install lookout-rack
155
+
156
+ § Usage
157
+
158
+ Include the following code in your ‹Rakefile› (provided that you’re using
159
+ Lookout-Rake¹):
160
+
161
+ require 'lookout-rack-3.0'
162
+
163
+ Lookout::Rake::Tasks::Test.new do |t|
164
+ t.requires << 'lookout-rack-3.0'
165
+ end
166
+
167
+ ¹ See http://disu.se/software/lookout-rake/
168
+
169
+ Then set up a ‹fixtures/config.ru› file that Lookout-Rack
170
+ will use for loading your Rack app.
171
+
172
+ load 'path/to/app.rb'
173
+ use Rack::Lint
174
+ run Path::To::App
175
+
176
+ This file, if it exists, will be loaded during the first call to #session.
177
+ If it doesn’t exist, ‹config.ru› will be used instead.
178
+
179
+ You can now test your app:
180
+
181
+ Expectations do
182
+ expect 200 do
183
+ session.get('/').response.status
184
+ end
185
+ end
186
+
187
+ The #session method returns an object that lets you #get, #post, #put, and
188
+ #delete resources from the Rack app. You call these method with a URI¹
189
+ that you want to access/modify together with any parameters that you want
190
+ to pass and any Rack environment that you want to use (which isn’t very
191
+ common). For example, let’s get ‹/pizzas/› with olives on them:
192
+
193
+ expect 200 do
194
+ session.get('/pizzas/', 'olives' => '1').response.status
195
+ end
196
+
197
+ ¹ Abbreviation for Uniform Resource Identifier
198
+
199
+ The #response method on #session returns a mock Rack response object that
200
+ can be queried for results. Similarly, there’s a #request method that lets
201
+ you inspect the request that was made.
202
+
203
+ Lookout-Rack also deals with cookies. Assuming that ‹/cookies/set/› will
204
+ set any cookies that we pass it and that ‹/cookies/show/› will simply do
205
+ nothing relevant, the following expectation will pass:
206
+
207
+ expect 'value' => '1' do
208
+ session.
209
+ get('/cookies/set/', 'value' => '1').
210
+ get('/cookies/show/').request.cookies
211
+ end
212
+
213
+ Sometimes you may want to set cookies yourself before making a request.
214
+ You then use the #cookie method, which takes a String of ‹KEY=VALUE› pairs
215
+ separated by newlines, commas, and/or semicolons and sets those cookies in
216
+ the session:
217
+
218
+ expect 'value' => '1', 'other' => '2' do
219
+ session.
220
+ cookie("value=1\n\nother=2").
221
+ get('/cookies/show/').request.cookies
222
+ end
223
+
224
+ You may also want to clear all cookies in your session using #clear:
225
+
226
+ expect({}) do
227
+ session.
228
+ get('/cookies/set', 'value' => '1').
229
+ clear.
230
+ get('/cookies/show').request.cookies
231
+ end
232
+
233
+ Finally, to test redirects, call the #redirect! method on the session
234
+ object, assuming that ‹/redirected/› redirects to another location:
235
+
236
+ expect result.redirect? do
237
+ session.get('/redirected/').response
238
+ end
239
+
240
+ expect result.not.redirect? do
241
+ session.get('/redirected/').redirect!.response
242
+ end
243
+
244
+ That’s basically all there’s to it. You can check the {API documentation}¹
245
+ for more information.
246
+
247
+ ¹ See http://disu.se/software/lookout-rack/api/Lookout/Rack/
248
+
249
+ § Financing
250
+
251
+ Currently, most of my time is spent at my day job and in my rather busy
252
+ private life. Please motivate me to spend time on this piece of software
253
+ by donating some of your money to this project. Yeah, I realize that
254
+ requesting money to develop software is a bit, well, capitalistic of me.
255
+ But please realize that I live in a capitalistic society and I need money
256
+ to have other people give me the things that I need to continue living
257
+ under the rules of said society. So, if you feel that this piece of
258
+ software has helped you out enough to warrant a reward, please PayPal a
259
+ donation to now@disu.se¹. Thanks! Your support won’t go unnoticed!
260
+
261
+ ¹ Send a donation:
262
+ https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=now@disu.se&item_name=Lookout-Rack
263
+
264
+ § Reporting Bugs
265
+
266
+ Please report any bugs that you encounter to the {issue tracker}¹.
267
+
268
+ ¹ See https://github.com/now/lookout-rack/issues
269
+
270
+ § Authors
271
+
272
+ Nikolai Weibull wrote the code, the tests, the documentation, and this
273
+ README.
274
+ email: now@bitwi.se
275
+ executables: []
276
+ extensions: []
277
+ extra_rdoc_files: []
278
+ files:
279
+ - lib/lookout-rack-1.0/cookie.rb
280
+ - lib/lookout-rack-1.0/cookies.rb
281
+ - lib/lookout-rack-1.0/methods.rb
282
+ - lib/lookout-rack-1.0/session.rb
283
+ - lib/lookout-rack-1.0.rb
284
+ - lib/lookout-rack-1.0/version.rb
285
+ - test/unit/lookout-rack-1.0/cookie.rb
286
+ - test/unit/lookout-rack-1.0/cookies.rb
287
+ - test/unit/lookout-rack-1.0/methods.rb
288
+ - test/unit/lookout-rack-1.0/session.rb
289
+ - test/unit/lookout-rack-1.0.rb
290
+ - test/unit/lookout-rack-1.0/version.rb
291
+ - fixtures/app.rb
292
+ - fixtures/config.ru
293
+ homepage: https://github.com/now/lookout-rack
294
+ licenses: []
295
+ metadata: {}
296
+ post_install_message:
297
+ rdoc_options: []
298
+ require_paths:
299
+ - lib
300
+ required_ruby_version: !ruby/object:Gem::Requirement
301
+ requirements:
302
+ - - '>='
303
+ - !ruby/object:Gem::Version
304
+ version: '0'
305
+ required_rubygems_version: !ruby/object:Gem::Requirement
306
+ requirements:
307
+ - - '>='
308
+ - !ruby/object:Gem::Version
309
+ version: '0'
310
+ requirements: []
311
+ rubyforge_project:
312
+ rubygems_version: 2.0.3
313
+ signing_key:
314
+ specification_version: 4
315
+ summary: Lookout-Rack provides easy interaction with Rack¹ from Lookout².
316
+ test_files: []