joebadmo-rack-test 0.6.1

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.
@@ -0,0 +1,82 @@
1
+ require "forwardable"
2
+
3
+ module Rack
4
+ module Test
5
+
6
+ # This module serves as the primary integration point for using Rack::Test
7
+ # in a testing environment. It depends on an app method being defined in the
8
+ # same context, and provides the Rack::Test API methods (see Rack::Test::Session
9
+ # for their documentation).
10
+ #
11
+ # Example:
12
+ #
13
+ # class HomepageTest < Test::Unit::TestCase
14
+ # include Rack::Test::Methods
15
+ #
16
+ # def app
17
+ # MyApp.new
18
+ # end
19
+ # end
20
+ module Methods
21
+ extend Forwardable
22
+
23
+ def rack_mock_session(name = :default) # :nodoc:
24
+ return build_rack_mock_session unless name
25
+
26
+ @_rack_mock_sessions ||= {}
27
+ @_rack_mock_sessions[name] ||= build_rack_mock_session
28
+ end
29
+
30
+ def build_rack_mock_session # :nodoc:
31
+ Rack::MockSession.new(app)
32
+ end
33
+
34
+ def rack_test_session(name = :default) # :nodoc:
35
+ return build_rack_test_session(name) unless name
36
+
37
+ @_rack_test_sessions ||= {}
38
+ @_rack_test_sessions[name] ||= build_rack_test_session(name)
39
+ end
40
+
41
+ def build_rack_test_session(name) # :nodoc:
42
+ Rack::Test::Session.new(rack_mock_session(name))
43
+ end
44
+
45
+ def current_session # :nodoc:
46
+ rack_test_session(_current_session_names.last)
47
+ end
48
+
49
+ def with_session(name) # :nodoc:
50
+ _current_session_names.push(name)
51
+ yield rack_test_session(name)
52
+ _current_session_names.pop
53
+ end
54
+
55
+ def _current_session_names # :nodoc:
56
+ @_current_session_names ||= [:default]
57
+ end
58
+
59
+ METHODS = [
60
+ :request,
61
+ :get,
62
+ :post,
63
+ :put,
64
+ :patch,
65
+ :delete,
66
+ :options,
67
+ :head,
68
+ :follow_redirect!,
69
+ :header,
70
+ :set_cookie,
71
+ :clear_cookies,
72
+ :authorize,
73
+ :basic_authorize,
74
+ :digest_authorize,
75
+ :last_response,
76
+ :last_request
77
+ ]
78
+
79
+ def_delegators :current_session, *METHODS
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,29 @@
1
+ module Rack
2
+ module Test
3
+
4
+ class MockDigestRequest # :nodoc:
5
+
6
+ def initialize(params)
7
+ @params = params
8
+ end
9
+
10
+ def method_missing(sym)
11
+ if @params.has_key? k = sym.to_s
12
+ return @params[k]
13
+ end
14
+
15
+ super
16
+ end
17
+
18
+ def method
19
+ @params['method']
20
+ end
21
+
22
+ def response(password)
23
+ Rack::Auth::Digest::MD5.new(nil).send :digest, self, password
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ require "tempfile"
2
+ require "fileutils"
3
+
4
+ module Rack
5
+ module Test
6
+
7
+ # Wraps a Tempfile with a content type. Including one or more UploadedFile's
8
+ # in the params causes Rack::Test to build and issue a multipart request.
9
+ #
10
+ # Example:
11
+ # post "/photos", "file" => Rack::Test::UploadedFile.new("me.jpg", "image/jpeg")
12
+ class UploadedFile
13
+
14
+ # The filename, *not* including the path, of the "uploaded" file
15
+ attr_reader :original_filename
16
+
17
+ # The content type of the "uploaded" file
18
+ attr_accessor :content_type
19
+
20
+ def initialize(path, content_type = "text/plain", binary = false)
21
+ raise "#{path} file does not exist" unless ::File.exist?(path)
22
+
23
+ @content_type = content_type
24
+ @original_filename = ::File.basename(path)
25
+
26
+ @tempfile = Tempfile.new(@original_filename)
27
+ @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
28
+ @tempfile.binmode if binary
29
+
30
+ FileUtils.copy_file(path, @tempfile.path)
31
+ end
32
+
33
+ def path
34
+ @tempfile.path
35
+ end
36
+
37
+ alias_method :local_path, :path
38
+
39
+ def method_missing(method_name, *args, &block) #:nodoc:
40
+ @tempfile.__send__(method_name, *args, &block)
41
+ end
42
+
43
+ def respond_to?(method_name, include_private = false) #:nodoc:
44
+ @tempfile.respond_to?(method_name, include_private) || super
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,136 @@
1
+ module Rack
2
+ module Test
3
+
4
+ module Utils # :nodoc:
5
+ include Rack::Utils
6
+
7
+ def build_nested_query(value, prefix = nil)
8
+ case value
9
+ when Array
10
+ value.map do |v|
11
+ unless unescape(prefix) =~ /\[\]$/
12
+ prefix = "#{prefix}[]"
13
+ end
14
+ build_nested_query(v, "#{prefix}")
15
+ end.join("&")
16
+ when Hash
17
+ value.map do |k, v|
18
+ build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
19
+ end.join("&")
20
+ when NilClass
21
+ prefix.to_s
22
+ else
23
+ "#{prefix}=#{escape(value)}"
24
+ end
25
+ end
26
+
27
+ module_function :build_nested_query
28
+
29
+ def build_multipart(params, first = true)
30
+ if first
31
+ unless params.is_a?(Hash)
32
+ raise ArgumentError, "value must be a Hash"
33
+ end
34
+
35
+ multipart = false
36
+ query = lambda { |value|
37
+ case value
38
+ when Array
39
+ value.each(&query)
40
+ when Hash
41
+ value.values.each(&query)
42
+ when UploadedFile
43
+ multipart = true
44
+ end
45
+ }
46
+ params.values.each(&query)
47
+ return nil unless multipart
48
+ end
49
+
50
+ flattened_params = Hash.new
51
+
52
+ params.each do |key, value|
53
+ k = first ? key.to_s : "[#{key}]"
54
+
55
+ case value
56
+ when Array
57
+ value.map do |v|
58
+
59
+ if (v.is_a?(Hash))
60
+ build_multipart(v, false).each { |subkey, subvalue|
61
+ flattened_params["#{k}[]#{subkey}"] = subvalue
62
+ }
63
+ else
64
+ flattened_params["#{k}[]"] = value
65
+ end
66
+
67
+ end
68
+ when Hash
69
+ build_multipart(value, false).each { |subkey, subvalue|
70
+ flattened_params[k + subkey] = subvalue
71
+ }
72
+ else
73
+ flattened_params[k] = value
74
+ end
75
+ end
76
+
77
+ if first
78
+ build_parts(flattened_params)
79
+ else
80
+ flattened_params
81
+ end
82
+ end
83
+
84
+ module_function :build_multipart
85
+
86
+ private
87
+ def build_parts(parameters)
88
+ parameters.map { |name, value|
89
+ if value.respond_to?(:original_filename)
90
+ build_file_part(name, value)
91
+
92
+ elsif value.is_a?(Array) and value.all? { |v| v.respond_to?(:original_filename) }
93
+ value.map do |v|
94
+ build_file_part(name, v)
95
+ end.join
96
+
97
+ else
98
+ primitive_part = build_primitive_part(name, value)
99
+ Rack::Test.encoding_aware_strings? ? primitive_part.force_encoding('BINARY') : primitive_part
100
+ end
101
+
102
+ }.join + "--#{MULTIPART_BOUNDARY}--\r"
103
+ end
104
+
105
+ def build_primitive_part(parameter_name, value)
106
+ unless value.is_a? Array
107
+ value = [value]
108
+ end
109
+ value.map do |v|
110
+ <<-EOF
111
+ --#{MULTIPART_BOUNDARY}\r
112
+ Content-Disposition: form-data; name="#{parameter_name}"\r
113
+ \r
114
+ #{v}\r
115
+ EOF
116
+ end.join
117
+ end
118
+
119
+ def build_file_part(parameter_name, uploaded_file)
120
+ ::File.open(uploaded_file.path, "rb") do |physical_file|
121
+ physical_file.set_encoding(Encoding::BINARY) if physical_file.respond_to?(:set_encoding)
122
+ <<-EOF
123
+ --#{MULTIPART_BOUNDARY}\r
124
+ Content-Disposition: form-data; name="#{parameter_name}"; filename="#{escape(uploaded_file.original_filename)}"\r
125
+ Content-Type: #{uploaded_file.content_type}\r
126
+ Content-Length: #{::File.stat(uploaded_file.path).size}\r
127
+ \r
128
+ #{physical_file.read}\r
129
+ EOF
130
+ end
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+ end
data/rack-test.gemspec ADDED
@@ -0,0 +1,80 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'joebadmo-rack-test'
5
+ s.version = "0.6.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Bryan Helmkamp"]
9
+ s.date = %q{2011-07-27}
10
+ s.description = %q{Rack::Test is a small, simple testing API for Rack apps. It can be used on its
11
+ own or as a reusable starting point for Web frameworks and testing libraries
12
+ to build on. Most of its initial functionality is an extraction of Merb 1.0's
13
+ request helpers feature.}
14
+ s.email = %q{bryan@brynary.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc",
17
+ "MIT-LICENSE.txt"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "History.txt",
25
+ "MIT-LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "Thorfile",
29
+ "lib/rack/mock_session.rb",
30
+ "lib/rack/test.rb",
31
+ "lib/rack/test/cookie_jar.rb",
32
+ "lib/rack/test/methods.rb",
33
+ "lib/rack/test/mock_digest_request.rb",
34
+ "lib/rack/test/uploaded_file.rb",
35
+ "lib/rack/test/utils.rb",
36
+ "rack-test.gemspec",
37
+ "spec/fixtures/bar.txt",
38
+ "spec/fixtures/config.ru",
39
+ "spec/fixtures/fake_app.rb",
40
+ "spec/fixtures/foo.txt",
41
+ "spec/rack/test/cookie_spec.rb",
42
+ "spec/rack/test/digest_auth_spec.rb",
43
+ "spec/rack/test/multipart_spec.rb",
44
+ "spec/rack/test/uploaded_file_spec.rb",
45
+ "spec/rack/test/utils_spec.rb",
46
+ "spec/rack/test_spec.rb",
47
+ "spec/spec_helper.rb",
48
+ "spec/support/matchers/body.rb",
49
+ "spec/support/matchers/challenge.rb"
50
+ ]
51
+ s.homepage = %q{http://github.com/brynary/rack-test}
52
+ s.require_paths = ["lib"]
53
+ s.rubyforge_project = %q{rack-test}
54
+ s.rubygems_version = %q{1.6.1}
55
+ s.summary = %q{Simple testing API built on Rack}
56
+ s.test_files = [
57
+ "spec/fixtures/fake_app.rb",
58
+ "spec/rack/test/cookie_spec.rb",
59
+ "spec/rack/test/digest_auth_spec.rb",
60
+ "spec/rack/test/multipart_spec.rb",
61
+ "spec/rack/test/uploaded_file_spec.rb",
62
+ "spec/rack/test/utils_spec.rb",
63
+ "spec/rack/test_spec.rb",
64
+ "spec/spec_helper.rb",
65
+ "spec/support/matchers/body.rb",
66
+ "spec/support/matchers/challenge.rb"
67
+ ]
68
+
69
+ if s.respond_to? :specification_version then
70
+ s.specification_version = 3
71
+
72
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
73
+ s.add_runtime_dependency(%q<rack>, [">= 1.0"])
74
+ else
75
+ s.add_dependency(%q<rack>, [">= 1.0"])
76
+ end
77
+ else
78
+ s.add_dependency(%q<rack>, [">= 1.0"])
79
+ end
80
+ end
@@ -0,0 +1 @@
1
+ baz
@@ -0,0 +1,3 @@
1
+ require "fake_app"
2
+
3
+ run Rack::Test::FakeApp
@@ -0,0 +1,143 @@
1
+ require "rubygems"
2
+ require "sinatra/base"
3
+
4
+ module Rack
5
+ module Test
6
+
7
+ class FakeApp < Sinatra::Base
8
+ head "/" do
9
+ "meh"
10
+ end
11
+
12
+ options "/" do
13
+ [200, {}, ""]
14
+ end
15
+
16
+ get "/" do
17
+ "Hello, GET: #{params.inspect}"
18
+ end
19
+
20
+ get "/redirect" do
21
+ redirect "/redirected"
22
+ end
23
+
24
+ get "/redirected" do
25
+ "You've been redirected"
26
+ end
27
+
28
+ get "/void" do
29
+ [200, {}, ""]
30
+ end
31
+
32
+ get "/cookies/show" do
33
+ request.cookies.inspect
34
+ end
35
+
36
+ get "/COOKIES/show" do
37
+ request.cookies.inspect
38
+ end
39
+
40
+ get "/not-cookies/show" do
41
+ request.cookies.inspect
42
+ end
43
+
44
+ get "/cookies/set-secure" do
45
+ raise if params["value"].nil?
46
+
47
+ response.set_cookie("secure-cookie", :value => params["value"], :secure => true)
48
+ "Set"
49
+ end
50
+
51
+ get "/cookies/set-simple" do
52
+ raise if params["value"].nil?
53
+
54
+ response.set_cookie "simple", params["value"]
55
+ "Set"
56
+ end
57
+
58
+ post "/cookies/default-path" do
59
+ raise if params["value"].nil?
60
+
61
+ response.set_cookie "simple", params["value"]
62
+ "Set"
63
+ end
64
+
65
+ get "/cookies/default-path" do
66
+ response.cookies.inspect
67
+ end
68
+
69
+ get "/cookies/delete" do
70
+ response.delete_cookie "value"
71
+ end
72
+
73
+ get "/cookies/count" do
74
+ old_value = request.cookies["count"].to_i || 0
75
+ new_value = (old_value + 1).to_s
76
+
77
+ response.set_cookie("count", :value => new_value)
78
+ new_value
79
+ end
80
+
81
+ get "/cookies/set" do
82
+ raise if params["value"].nil?
83
+
84
+ response.set_cookie("value", {
85
+ :value => params["value"],
86
+ :path => "/cookies",
87
+ :expires => Time.now + 10
88
+ })
89
+ "Set"
90
+ end
91
+
92
+ get "/cookies/domain" do
93
+ old_value = request.cookies["count"].to_i || 0
94
+ new_value = (old_value + 1).to_s
95
+
96
+ response.set_cookie("count", :value => new_value, :domain => "localhost.com")
97
+ new_value
98
+ end
99
+
100
+ get "/cookies/subdomain" do
101
+ old_value = request.cookies["count"].to_i || 0
102
+ new_value = (old_value + 1).to_s
103
+
104
+ response.set_cookie("count", :value => new_value, :domain => ".example.org")
105
+ new_value
106
+ end
107
+
108
+ get "/cookies/set-uppercase" do
109
+ raise if params["value"].nil?
110
+
111
+ response.set_cookie("VALUE", {
112
+ :value => params["value"],
113
+ :path => "/cookies",
114
+ :expires => Time.now + 10
115
+ })
116
+ "Set"
117
+ end
118
+
119
+ get "/cookies/set-multiple" do
120
+ response.set_cookie("key1", :value => "value1")
121
+ response.set_cookie("key2", :value => "value2")
122
+ "Set"
123
+ end
124
+
125
+ post "/" do
126
+ "Hello, POST: #{params.inspect}"
127
+ end
128
+
129
+ put "/" do
130
+ "Hello, PUT: #{params.inspect}"
131
+ end
132
+
133
+ patch "/" do
134
+ "Hello, PUT: #{params.inspect}"
135
+ end
136
+
137
+ delete "/" do
138
+ "Hello, DELETE: #{params.inspect}"
139
+ end
140
+ end
141
+
142
+ end
143
+ end