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 +7 -0
- data/fixtures/app.rb +102 -0
- data/fixtures/config.ru +5 -0
- data/lib/lookout-rack-1.0.rb +35 -0
- data/lib/lookout-rack-1.0/cookie.rb +79 -0
- data/lib/lookout-rack-1.0/cookies.rb +21 -0
- data/lib/lookout-rack-1.0/methods.rb +19 -0
- data/lib/lookout-rack-1.0/session.rb +116 -0
- data/lib/lookout-rack-1.0/version.rb +37 -0
- data/test/unit/lookout-rack-1.0.rb +4 -0
- data/test/unit/lookout-rack-1.0/cookie.rb +4 -0
- data/test/unit/lookout-rack-1.0/cookies.rb +4 -0
- data/test/unit/lookout-rack-1.0/methods.rb +4 -0
- data/test/unit/lookout-rack-1.0/session.rb +169 -0
- data/test/unit/lookout-rack-1.0/version.rb +4 -0
- metadata +316 -0
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
|
data/fixtures/config.ru
ADDED
@@ -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,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
|
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: []
|