summary refs log tree commit
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2022-02-04 14:31:26 -0800
committerGitHub <noreply@github.com>2022-02-04 14:31:26 -0800
commitf04b83debdf6b74e5f97115e7029e8e11e69df6b (patch)
tree06051fb52f0fa1f3d163a8bd7c94b57725f62efe
parent80e6f6b2e8e74dbcae89493e80cd9870a294ae7f (diff)
parent2833813bd7f2a1872831d83cc9a0bb60f7d94fdd (diff)
downloadrack-f04b83debdf6b74e5f97115e7029e8e11e69df6b.tar.gz
Merge pull request #1801 from jeremyevans/require-part-testing
Enable directly requiring Rack components
-rw-r--r--Rakefile18
-rw-r--r--lib/rack.rb59
-rw-r--r--lib/rack/auth/abstract/handler.rb2
-rw-r--r--lib/rack/auth/abstract/request.rb2
-rw-r--r--lib/rack/builder.rb2
-rw-r--r--lib/rack/cascade.rb2
-rw-r--r--lib/rack/chunked.rb3
-rw-r--r--lib/rack/common_logger.rb4
-rw-r--r--lib/rack/conditional_get.rb4
-rw-r--r--lib/rack/constants.rb61
-rw-r--r--lib/rack/content_length.rb3
-rw-r--r--lib/rack/content_type.rb3
-rw-r--r--lib/rack/deflater.rb5
-rw-r--r--lib/rack/directory.rb6
-rw-r--r--lib/rack/etag.rb4
-rw-r--r--lib/rack/events.rb4
-rw-r--r--lib/rack/files.rb6
-rw-r--r--lib/rack/handler/webrick.rb3
-rw-r--r--lib/rack/head.rb3
-rwxr-xr-xlib/rack/lint.rb3
-rw-r--r--lib/rack/lobster.rb8
-rw-r--r--lib/rack/lock.rb2
-rw-r--r--lib/rack/logger.rb2
-rw-r--r--lib/rack/method_override.rb4
-rw-r--r--lib/rack/mock.rb5
-rw-r--r--lib/rack/multipart.rb6
-rw-r--r--lib/rack/multipart/generator.rb2
-rw-r--r--lib/rack/multipart/parser.rb4
-rw-r--r--lib/rack/multipart/uploaded_file.rb4
-rw-r--r--lib/rack/null_logger.rb2
-rw-r--r--lib/rack/recursive.rb2
-rw-r--r--lib/rack/request.rb6
-rw-r--r--lib/rack/response.rb4
-rw-r--r--lib/rack/runtime.rb2
-rw-r--r--lib/rack/sendfile.rb4
-rw-r--r--lib/rack/server.rb9
-rw-r--r--lib/rack/session/abstract/id.rb5
-rw-r--r--lib/rack/session/cookie.rb5
-rw-r--r--lib/rack/session/pool.rb1
-rw-r--r--lib/rack/show_exceptions.rb4
-rw-r--r--lib/rack/show_status.rb5
-rw-r--r--lib/rack/static.rb4
-rw-r--r--lib/rack/tempfile_reaper.rb3
-rw-r--r--lib/rack/urlmap.rb2
-rw-r--r--lib/rack/utils.rb1
-rw-r--r--test/helper.rb11
-rw-r--r--test/psych_fix.rb8
-rw-r--r--test/spec_auth_basic.rb6
-rw-r--r--test/spec_auth_digest.rb10
-rw-r--r--test/spec_body_proxy.rb4
-rw-r--r--test/spec_builder.rb9
-rw-r--r--test/spec_cascade.rb8
-rw-r--r--test/spec_chunked.rb6
-rw-r--r--test/spec_common_logger.rb6
-rw-r--r--test/spec_conditional_get.rb6
-rw-r--r--test/spec_config.rb7
-rw-r--r--test/spec_content_length.rb6
-rw-r--r--test/spec_content_type.rb6
-rw-r--r--test/spec_deflater.rb6
-rw-r--r--test/spec_directory.rb8
-rw-r--r--test/spec_etag.rb6
-rw-r--r--test/spec_events.rb4
-rw-r--r--test/spec_files.rb6
-rw-r--r--test/spec_handler.rb4
-rw-r--r--test/spec_head.rb6
-rwxr-xr-xtest/spec_lint.rb5
-rw-r--r--test/spec_lobster.rb7
-rw-r--r--test/spec_lock.rb6
-rw-r--r--test/spec_logger.rb6
-rw-r--r--test/spec_media_type.rb4
-rw-r--r--test/spec_method_override.rb6
-rw-r--r--test/spec_mime.rb4
-rw-r--r--test/spec_mock.rb18
-rw-r--r--test/spec_multipart.rb8
-rw-r--r--test/spec_null_logger.rb6
-rw-r--r--test/spec_recursive.rb7
-rw-r--r--test/spec_request.rb6
-rw-r--r--test/spec_response.rb4
-rw-r--r--test/spec_rewindable_input.rb4
-rw-r--r--test/spec_runtime.rb6
-rw-r--r--test/spec_sendfile.rb6
-rw-r--r--test/spec_server.rb10
-rw-r--r--test/spec_session_abstract_id.rb5
-rw-r--r--test/spec_session_abstract_persisted.rb6
-rw-r--r--test/spec_session_abstract_persisted_secure_secure_session_hash.rb6
-rw-r--r--test/spec_session_abstract_session_hash.rb4
-rw-r--r--test/spec_session_cookie.rb7
-rw-r--r--test/spec_session_pool.rb8
-rw-r--r--test/spec_show_exceptions.rb6
-rw-r--r--test/spec_show_status.rb6
-rw-r--r--test/spec_static.rb6
-rw-r--r--test/spec_tempfile_reaper.rb6
-rw-r--r--test/spec_urlmap.rb6
-rw-r--r--test/spec_utils.rb8
-rw-r--r--test/spec_version.rb4
-rw-r--r--test/spec_webrick.rb7
-rw-r--r--test/test_request.rb1
97 files changed, 545 insertions, 80 deletions
diff --git a/Rakefile b/Rakefile
index 88cf6621..7848b0c0 100644
--- a/Rakefile
+++ b/Rakefile
@@ -98,8 +98,24 @@ task "test_cov" do
   Rake::Task['test:regular'].invoke
 end
 
+desc "Run separate tests for each test file, to test directly requiring components"
+task "test:separate" do
+  fails = []
+  FileList["test/**/spec_*.rb"].each do |file|
+    puts "#{FileUtils::RUBY} -w #{file}"
+    fails << file unless system({'SEPARATE'=>'1'},  FileUtils::RUBY, '-w', file)
+  end
+  if fails.empty?
+    puts 'All test files passed'
+  else
+    puts "Failures in the following test files:"
+    puts fails
+    raise "At least one separate test failed"
+  end
+end
+
 desc "Run all the fast + platform agnostic tests"
-task test: %w[spec test:regular]
+task test: %w[spec test:regular test:separate]
 
 desc "Run all the tests we run on CI"
 task ci: :test
diff --git a/lib/rack.rb b/lib/rack.rb
index 1df65b47..6ec8bad7 100644
--- a/lib/rack.rb
+++ b/lib/rack.rb
@@ -12,66 +12,9 @@
 # so it should be enough just to <tt>require 'rack'</tt> in your code.
 
 require_relative 'rack/version'
+require_relative 'rack/constants'
 
 module Rack
-  HTTP_HOST         = 'HTTP_HOST'
-  HTTP_PORT         = 'HTTP_PORT'
-  HTTPS             = 'HTTPS'
-  PATH_INFO         = 'PATH_INFO'
-  REQUEST_METHOD    = 'REQUEST_METHOD'
-  REQUEST_PATH      = 'REQUEST_PATH'
-  SCRIPT_NAME       = 'SCRIPT_NAME'
-  QUERY_STRING      = 'QUERY_STRING'
-  SERVER_PROTOCOL   = 'SERVER_PROTOCOL'
-  SERVER_NAME       = 'SERVER_NAME'
-  SERVER_PORT       = 'SERVER_PORT'
-  CACHE_CONTROL     = 'Cache-Control'
-  EXPIRES           = 'Expires'
-  CONTENT_LENGTH    = 'Content-Length'
-  CONTENT_TYPE      = 'Content-Type'
-  SET_COOKIE        = 'Set-Cookie'
-  TRANSFER_ENCODING = 'Transfer-Encoding'
-  HTTP_COOKIE       = 'HTTP_COOKIE'
-  ETAG              = 'ETag'
-
-  # HTTP method verbs
-  GET     = 'GET'
-  POST    = 'POST'
-  PUT     = 'PUT'
-  PATCH   = 'PATCH'
-  DELETE  = 'DELETE'
-  HEAD    = 'HEAD'
-  OPTIONS = 'OPTIONS'
-  LINK    = 'LINK'
-  UNLINK  = 'UNLINK'
-  TRACE   = 'TRACE'
-
-  # Rack environment variables
-  RACK_VERSION                        = 'rack.version'
-  RACK_TEMPFILES                      = 'rack.tempfiles'
-  RACK_ERRORS                         = 'rack.errors'
-  RACK_LOGGER                         = 'rack.logger'
-  RACK_INPUT                          = 'rack.input'
-  RACK_SESSION                        = 'rack.session'
-  RACK_SESSION_OPTIONS                = 'rack.session.options'
-  RACK_SHOWSTATUS_DETAIL              = 'rack.showstatus.detail'
-  RACK_URL_SCHEME                     = 'rack.url_scheme'
-  RACK_HIJACK                         = 'rack.hijack'
-  RACK_IS_HIJACK                      = 'rack.hijack?'
-  RACK_HIJACK_IO                      = 'rack.hijack_io'
-  RACK_RECURSIVE_INCLUDE              = 'rack.recursive.include'
-  RACK_MULTIPART_BUFFER_SIZE          = 'rack.multipart.buffer_size'
-  RACK_MULTIPART_TEMPFILE_FACTORY     = 'rack.multipart.tempfile_factory'
-  RACK_REQUEST_FORM_INPUT             = 'rack.request.form_input'
-  RACK_REQUEST_FORM_HASH              = 'rack.request.form_hash'
-  RACK_REQUEST_FORM_VARS              = 'rack.request.form_vars'
-  RACK_REQUEST_COOKIE_HASH            = 'rack.request.cookie_hash'
-  RACK_REQUEST_COOKIE_STRING          = 'rack.request.cookie_string'
-  RACK_REQUEST_QUERY_HASH             = 'rack.request.query_hash'
-  RACK_REQUEST_QUERY_STRING           = 'rack.request.query_string'
-  RACK_METHODOVERRIDE_ORIGINAL_METHOD = 'rack.methodoverride.original_method'
-  RACK_SESSION_UNPACKED_COOKIE_DATA   = 'rack.session.unpacked_cookie_data'
-
   autoload :Builder, "rack/builder"
   autoload :BodyProxy, "rack/body_proxy"
   autoload :Cascade, "rack/cascade"
diff --git a/lib/rack/auth/abstract/handler.rb b/lib/rack/auth/abstract/handler.rb
index 3ed87091..8a963dab 100644
--- a/lib/rack/auth/abstract/handler.rb
+++ b/lib/rack/auth/abstract/handler.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative '../../constants'
+
 module Rack
   module Auth
     # Rack::Auth::AbstractHandler implements common authentication functionality.
diff --git a/lib/rack/auth/abstract/request.rb b/lib/rack/auth/abstract/request.rb
index 7b499f1b..f8723315 100644
--- a/lib/rack/auth/abstract/request.rb
+++ b/lib/rack/auth/abstract/request.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative '../../request'
+
 module Rack
   module Auth
     class AbstractRequest
diff --git a/lib/rack/builder.rb b/lib/rack/builder.rb
index 3dcecb55..9ef656c1 100644
--- a/lib/rack/builder.rb
+++ b/lib/rack/builder.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative 'urlmap'
+
 module Rack
   # Rack::Builder implements a small DSL to iteratively construct Rack
   # applications.
diff --git a/lib/rack/cascade.rb b/lib/rack/cascade.rb
index d71274c2..027d7e40 100644
--- a/lib/rack/cascade.rb
+++ b/lib/rack/cascade.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+
 module Rack
   # Rack::Cascade tries a request on several apps, and returns the
   # first response that is not 404 or 405 (or in a list of configured
diff --git a/lib/rack/chunked.rb b/lib/rack/chunked.rb
index 84c66001..f880dd85 100644
--- a/lib/rack/chunked.rb
+++ b/lib/rack/chunked.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'utils'
+
 module Rack
 
   # Middleware that applies chunked transfer encoding to response bodies
diff --git a/lib/rack/common_logger.rb b/lib/rack/common_logger.rb
index 4acd11ff..30456e50 100644
--- a/lib/rack/common_logger.rb
+++ b/lib/rack/common_logger.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'body_proxy'
+
 module Rack
   # Rack::CommonLogger forwards every request to the given +app+, and
   # logs a line in the
diff --git a/lib/rack/conditional_get.rb b/lib/rack/conditional_get.rb
index 7b7808ac..d56f1454 100644
--- a/lib/rack/conditional_get.rb
+++ b/lib/rack/conditional_get.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'body_proxy'
+
 module Rack
 
   # Middleware that enables conditional GET using If-None-Match and
diff --git a/lib/rack/constants.rb b/lib/rack/constants.rb
new file mode 100644
index 00000000..55cfd9fe
--- /dev/null
+++ b/lib/rack/constants.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Rack
+  HTTP_HOST         = 'HTTP_HOST'
+  HTTP_PORT         = 'HTTP_PORT'
+  HTTPS             = 'HTTPS'
+  PATH_INFO         = 'PATH_INFO'
+  REQUEST_METHOD    = 'REQUEST_METHOD'
+  REQUEST_PATH      = 'REQUEST_PATH'
+  SCRIPT_NAME       = 'SCRIPT_NAME'
+  QUERY_STRING      = 'QUERY_STRING'
+  SERVER_PROTOCOL   = 'SERVER_PROTOCOL'
+  SERVER_NAME       = 'SERVER_NAME'
+  SERVER_PORT       = 'SERVER_PORT'
+  CACHE_CONTROL     = 'Cache-Control'
+  EXPIRES           = 'Expires'
+  CONTENT_LENGTH    = 'Content-Length'
+  CONTENT_TYPE      = 'Content-Type'
+  SET_COOKIE        = 'Set-Cookie'
+  TRANSFER_ENCODING = 'Transfer-Encoding'
+  HTTP_COOKIE       = 'HTTP_COOKIE'
+  ETAG              = 'ETag'
+
+  # HTTP method verbs
+  GET     = 'GET'
+  POST    = 'POST'
+  PUT     = 'PUT'
+  PATCH   = 'PATCH'
+  DELETE  = 'DELETE'
+  HEAD    = 'HEAD'
+  OPTIONS = 'OPTIONS'
+  LINK    = 'LINK'
+  UNLINK  = 'UNLINK'
+  TRACE   = 'TRACE'
+
+  # Rack environment variables
+  RACK_VERSION                        = 'rack.version'
+  RACK_TEMPFILES                      = 'rack.tempfiles'
+  RACK_ERRORS                         = 'rack.errors'
+  RACK_LOGGER                         = 'rack.logger'
+  RACK_INPUT                          = 'rack.input'
+  RACK_SESSION                        = 'rack.session'
+  RACK_SESSION_OPTIONS                = 'rack.session.options'
+  RACK_SHOWSTATUS_DETAIL              = 'rack.showstatus.detail'
+  RACK_URL_SCHEME                     = 'rack.url_scheme'
+  RACK_HIJACK                         = 'rack.hijack'
+  RACK_IS_HIJACK                      = 'rack.hijack?'
+  RACK_HIJACK_IO                      = 'rack.hijack_io'
+  RACK_RECURSIVE_INCLUDE              = 'rack.recursive.include'
+  RACK_MULTIPART_BUFFER_SIZE          = 'rack.multipart.buffer_size'
+  RACK_MULTIPART_TEMPFILE_FACTORY     = 'rack.multipart.tempfile_factory'
+  RACK_REQUEST_FORM_INPUT             = 'rack.request.form_input'
+  RACK_REQUEST_FORM_HASH              = 'rack.request.form_hash'
+  RACK_REQUEST_FORM_VARS              = 'rack.request.form_vars'
+  RACK_REQUEST_COOKIE_HASH            = 'rack.request.cookie_hash'
+  RACK_REQUEST_COOKIE_STRING          = 'rack.request.cookie_string'
+  RACK_REQUEST_QUERY_HASH             = 'rack.request.query_hash'
+  RACK_REQUEST_QUERY_STRING           = 'rack.request.query_string'
+  RACK_METHODOVERRIDE_ORIGINAL_METHOD = 'rack.methodoverride.original_method'
+  RACK_SESSION_UNPACKED_COOKIE_DATA   = 'rack.session.unpacked_cookie_data'
+end
diff --git a/lib/rack/content_length.rb b/lib/rack/content_length.rb
index 48e91cfc..b82707dd 100644
--- a/lib/rack/content_length.rb
+++ b/lib/rack/content_length.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'utils'
+
 module Rack
 
   # Sets the Content-Length header on responses that do not specify
diff --git a/lib/rack/content_type.rb b/lib/rack/content_type.rb
index 503f7070..e37011b9 100644
--- a/lib/rack/content_type.rb
+++ b/lib/rack/content_type.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'utils'
+
 module Rack
 
   # Sets the Content-Type header on responses which don't have one.
diff --git a/lib/rack/deflater.rb b/lib/rack/deflater.rb
index a8d418a6..372ad615 100644
--- a/lib/rack/deflater.rb
+++ b/lib/rack/deflater.rb
@@ -3,6 +3,11 @@
 require "zlib"
 require "time"  # for Time.httpdate
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'request'
+require_relative 'body_proxy'
+
 module Rack
   # This middleware enables content encoding of http responses,
   # usually for purposes of compression.
diff --git a/lib/rack/directory.rb b/lib/rack/directory.rb
index be72be01..ebc131e9 100644
--- a/lib/rack/directory.rb
+++ b/lib/rack/directory.rb
@@ -2,6 +2,12 @@
 
 require 'time'
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'head'
+require_relative 'mime'
+require_relative 'files'
+
 module Rack
   # Rack::Directory serves entries below the +root+ given, according to the
   # path info of the Rack request. If a directory is found, the file's contents
diff --git a/lib/rack/etag.rb b/lib/rack/etag.rb
index 4717c2c4..c5626f70 100644
--- a/lib/rack/etag.rb
+++ b/lib/rack/etag.rb
@@ -1,8 +1,10 @@
 # frozen_string_literal: true
 
-require_relative '../rack'
 require 'digest/sha2'
 
+require_relative 'constants'
+require_relative 'utils'
+
 module Rack
   # Automatically sets the ETag header on all String bodies.
   #
diff --git a/lib/rack/events.rb b/lib/rack/events.rb
index 65055fdc..c7bb201f 100644
--- a/lib/rack/events.rb
+++ b/lib/rack/events.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require_relative 'body_proxy'
+require_relative 'request'
+require_relative 'response'
+
 module Rack
   ### This middleware provides hooks to certain places in the request /
   # response lifecycle.  This is so that middleware that don't need to filter
diff --git a/lib/rack/files.rb b/lib/rack/files.rb
index e745eb39..c7810e40 100644
--- a/lib/rack/files.rb
+++ b/lib/rack/files.rb
@@ -2,6 +2,12 @@
 
 require 'time'
 
+require_relative 'constants'
+require_relative 'head'
+require_relative 'utils'
+require_relative 'request'
+require_relative 'mime'
+
 module Rack
   # Rack::Files serves files below the +root+ directory given, according to the
   # path info of the Rack request.
diff --git a/lib/rack/handler/webrick.rb b/lib/rack/handler/webrick.rb
index 9ce73b40..a96587e2 100644
--- a/lib/rack/handler/webrick.rb
+++ b/lib/rack/handler/webrick.rb
@@ -3,6 +3,9 @@
 require 'webrick'
 require 'stringio'
 
+require_relative '../constants'
+require_relative '../version'
+
 # This monkey patch allows for applications to perform their own chunking
 # through WEBrick::HTTPResponse if rack is set to true.
 class WEBrick::HTTPResponse
diff --git a/lib/rack/head.rb b/lib/rack/head.rb
index 8025a27d..3bd9a75b 100644
--- a/lib/rack/head.rb
+++ b/lib/rack/head.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'body_proxy'
+
 module Rack
   # Rack::Head returns an empty body for all HEAD requests. It leaves
   # all other requests unchanged.
diff --git a/lib/rack/lint.rb b/lib/rack/lint.rb
index fe616138..9f4ab065 100755
--- a/lib/rack/lint.rb
+++ b/lib/rack/lint.rb
@@ -2,6 +2,9 @@
 
 require 'forwardable'
 
+require_relative 'constants'
+require_relative 'utils'
+
 module Rack
   # Rack::Lint validates your application and the requests and
   # responses according to the Rack spec.
diff --git a/lib/rack/lobster.rb b/lib/rack/lobster.rb
index b86a625d..ede7f909 100644
--- a/lib/rack/lobster.rb
+++ b/lib/rack/lobster.rb
@@ -2,6 +2,10 @@
 
 require 'zlib'
 
+require_relative 'constants'
+require_relative 'request'
+require_relative 'response'
+
 module Rack
   # Paste has a Pony, Rack has a Lobster!
   class Lobster
@@ -62,7 +66,9 @@ end
 
 if $0 == __FILE__
   # :nocov:
-  require_relative '../rack'
+  require_relative 'server'
+  require_relative 'show_exceptions'
+  require_relative 'lint'
   Rack::Server.start(
     app: Rack::ShowExceptions.new(Rack::Lint.new(Rack::Lobster.new)), Port: 9292
   )
diff --git a/lib/rack/lock.rb b/lib/rack/lock.rb
index 3b084c28..342123a0 100644
--- a/lib/rack/lock.rb
+++ b/lib/rack/lock.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative 'body_proxy'
+
 module Rack
   # Rack::Lock locks every request inside a mutex, so that every request
   # will effectively be executed synchronously.
diff --git a/lib/rack/logger.rb b/lib/rack/logger.rb
index 6c4bede0..bdcc0690 100644
--- a/lib/rack/logger.rb
+++ b/lib/rack/logger.rb
@@ -2,6 +2,8 @@
 
 require 'logger'
 
+require_relative 'constants'
+
 module Rack
   # Sets up rack.logger to write to rack.errors stream
   class Logger
diff --git a/lib/rack/method_override.rb b/lib/rack/method_override.rb
index 453901fc..cf7fcf75 100644
--- a/lib/rack/method_override.rb
+++ b/lib/rack/method_override.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'request'
+require_relative 'utils'
+
 module Rack
   class MethodOverride
     HTTP_METHODS = %w[GET HEAD PUT POST DELETE OPTIONS PATCH LINK UNLINK]
diff --git a/lib/rack/mock.rb b/lib/rack/mock.rb
index c4f39b63..c0f348bb 100644
--- a/lib/rack/mock.rb
+++ b/lib/rack/mock.rb
@@ -2,10 +2,13 @@
 
 require 'uri'
 require 'stringio'
-require_relative '../rack'
 require 'cgi/cookie'
 require 'time'
 
+require_relative 'response'
+require_relative 'version'
+require_relative 'constants'
+
 module Rack
   # Rack::MockRequest helps testing your Rack application without
   # actually using HTTP.
diff --git a/lib/rack/multipart.rb b/lib/rack/multipart.rb
index 45f43bb6..9c2887e5 100644
--- a/lib/rack/multipart.rb
+++ b/lib/rack/multipart.rb
@@ -1,6 +1,7 @@
 # frozen_string_literal: true
 
-require_relative 'multipart/parser'
+require_relative 'constants'
+require_relative 'utils'
 
 module Rack
   # A multipart form data parser, adapted from IOWA.
@@ -63,3 +64,6 @@ module Rack
 
   end
 end
+
+require_relative 'request' unless defined?(Rack::Request)
+require_relative 'multipart/parser'
diff --git a/lib/rack/multipart/generator.rb b/lib/rack/multipart/generator.rb
index 8ba1a578..8edb3d6a 100644
--- a/lib/rack/multipart/generator.rb
+++ b/lib/rack/multipart/generator.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative '../multipart'
+
 module Rack
   module Multipart
     class Generator
diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb
index 3a6e0717..ce50e03e 100644
--- a/lib/rack/multipart/parser.rb
+++ b/lib/rack/multipart/parser.rb
@@ -2,6 +2,10 @@
 
 require 'strscan'
 
+require_relative '../auth/digest/params'
+require_relative '../utils'
+require_relative '../multipart' unless defined?(Rack::Multipart)
+
 module Rack
   module Multipart
     class MultipartPartLimitError < Errno::EMFILE; end
diff --git a/lib/rack/multipart/uploaded_file.rb b/lib/rack/multipart/uploaded_file.rb
index 9eaf6912..a8db0931 100644
--- a/lib/rack/multipart/uploaded_file.rb
+++ b/lib/rack/multipart/uploaded_file.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require 'tempfile'
+require 'fileutils'
+require_relative '../multipart'
+
 module Rack
   module Multipart
     class UploadedFile
diff --git a/lib/rack/null_logger.rb b/lib/rack/null_logger.rb
index d4ec3968..46262257 100644
--- a/lib/rack/null_logger.rb
+++ b/lib/rack/null_logger.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+
 module Rack
   class NullLogger
     def initialize(app)
diff --git a/lib/rack/recursive.rb b/lib/rack/recursive.rb
index 6971cbfd..0945d322 100644
--- a/lib/rack/recursive.rb
+++ b/lib/rack/recursive.rb
@@ -2,6 +2,8 @@
 
 require 'uri'
 
+require_relative 'constants'
+
 module Rack
   # Rack::ForwardRequest gets caught by Rack::Recursive and redirects
   # the current request to the app at +url+.
diff --git a/lib/rack/request.rb b/lib/rack/request.rb
index 1ac50087..9f1c2ce9 100644
--- a/lib/rack/request.rb
+++ b/lib/rack/request.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'media_type'
+
 module Rack
   # Rack::Request provides a convenient interface to a Rack
   # environment.  It is stateless, the environment +env+ passed to the
@@ -660,3 +664,5 @@ module Rack
     include Helpers
   end
 end
+
+require_relative 'multipart' unless defined?(Rack::Multipart)
diff --git a/lib/rack/response.rb b/lib/rack/response.rb
index 593208fe..d6f4c43d 100644
--- a/lib/rack/response.rb
+++ b/lib/rack/response.rb
@@ -2,6 +2,10 @@
 
 require 'time'
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'media_type'
+
 module Rack
   # Rack::Response provides a convenient interface to create a Rack
   # response.
diff --git a/lib/rack/runtime.rb b/lib/rack/runtime.rb
index d9b2d8ed..97762b37 100644
--- a/lib/rack/runtime.rb
+++ b/lib/rack/runtime.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative 'utils'
+
 module Rack
   # Sets an "X-Runtime" response header, indicating the response
   # time of the request, in seconds
diff --git a/lib/rack/sendfile.rb b/lib/rack/sendfile.rb
index 758a48d6..6eccbce2 100644
--- a/lib/rack/sendfile.rb
+++ b/lib/rack/sendfile.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'body_proxy'
+
 module Rack
 
   # = Sendfile
diff --git a/lib/rack/server.rb b/lib/rack/server.rb
index 5a1b45b9..b9034cb5 100644
--- a/lib/rack/server.rb
+++ b/lib/rack/server.rb
@@ -3,6 +3,15 @@
 require 'optparse'
 require 'fileutils'
 
+require_relative 'version'
+require_relative 'handler'
+require_relative 'builder'
+require_relative 'common_logger'
+require_relative 'content_length'
+require_relative 'show_exceptions'
+require_relative 'lint'
+require_relative 'tempfile_reaper'
+
 module Rack
 
   class Server
diff --git a/lib/rack/session/abstract/id.rb b/lib/rack/session/abstract/id.rb
index 80b0f68e..65b93d69 100644
--- a/lib/rack/session/abstract/id.rb
+++ b/lib/rack/session/abstract/id.rb
@@ -3,11 +3,14 @@
 # AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
 # bugrep: Andreas Zehnder
 
-require_relative '../../../rack'
 require 'time'
 require 'securerandom'
 require 'digest/sha2'
 
+require_relative '../../constants'
+require_relative '../../request'
+require_relative '../../response'
+
 module Rack
 
   module Session
diff --git a/lib/rack/session/cookie.rb b/lib/rack/session/cookie.rb
index 773d0b8f..653f9539 100644
--- a/lib/rack/session/cookie.rb
+++ b/lib/rack/session/cookie.rb
@@ -2,11 +2,14 @@
 
 require 'openssl'
 require 'zlib'
-require_relative 'abstract/id'
 require 'json'
 require 'base64'
 require 'delegate'
 
+require_relative '../constants'
+require_relative '../utils'
+require_relative 'abstract/id'
+
 module Rack
 
   module Session
diff --git a/lib/rack/session/pool.rb b/lib/rack/session/pool.rb
index 83a359fb..05c567d0 100644
--- a/lib/rack/session/pool.rb
+++ b/lib/rack/session/pool.rb
@@ -6,7 +6,6 @@
 #   sergio, threadiness and bugreps
 
 require_relative 'abstract/id'
-require 'thread'
 
 module Rack
   module Session
diff --git a/lib/rack/show_exceptions.rb b/lib/rack/show_exceptions.rb
index 07e60388..5f2bd7fb 100644
--- a/lib/rack/show_exceptions.rb
+++ b/lib/rack/show_exceptions.rb
@@ -3,6 +3,10 @@
 require 'ostruct'
 require 'erb'
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'request'
+
 module Rack
   # Rack::ShowExceptions catches all exceptions raised from the app it
   # wraps.  It shows a useful backtrace with the sourcefile and
diff --git a/lib/rack/show_status.rb b/lib/rack/show_status.rb
index d2593081..6cdff44a 100644
--- a/lib/rack/show_status.rb
+++ b/lib/rack/show_status.rb
@@ -2,6 +2,11 @@
 
 require 'erb'
 
+require_relative 'constants'
+require_relative 'utils'
+require_relative 'request'
+require_relative 'body_proxy'
+
 module Rack
   # Rack::ShowStatus catches all empty responses and replaces them
   # with a site explaining the error.
diff --git a/lib/rack/static.rb b/lib/rack/static.rb
index 88b0a802..e14cd6bb 100644
--- a/lib/rack/static.rb
+++ b/lib/rack/static.rb
@@ -1,5 +1,9 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'files'
+require_relative 'mime'
+
 module Rack
 
   # The Rack::Static middleware intercepts requests for static files
diff --git a/lib/rack/tempfile_reaper.rb b/lib/rack/tempfile_reaper.rb
index 12500f0a..6af0b662 100644
--- a/lib/rack/tempfile_reaper.rb
+++ b/lib/rack/tempfile_reaper.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+require_relative 'constants'
+require_relative 'body_proxy'
+
 module Rack
 
   # Middleware tracks and cleans Tempfiles created throughout a request (i.e. Rack::Multipart)
diff --git a/lib/rack/urlmap.rb b/lib/rack/urlmap.rb
index 31a642c4..c42fedb8 100644
--- a/lib/rack/urlmap.rb
+++ b/lib/rack/urlmap.rb
@@ -2,6 +2,8 @@
 
 require 'set'
 
+require_relative 'constants'
+
 module Rack
   # Rack::URLMap takes a hash mapping urls or paths to apps, and
   # dispatches accordingly.  Support for HTTP/1.1 host names exists if
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb
index 7d7719c0..20718277 100644
--- a/lib/rack/utils.rb
+++ b/lib/rack/utils.rb
@@ -8,6 +8,7 @@ require 'tempfile'
 require 'time'
 
 require_relative 'query_parser'
+require_relative 'mime'
 
 module Rack
   # Rack::Utils contains a grab-bag of useful methods for writing web
diff --git a/test/helper.rb b/test/helper.rb
index 55799c8c..83f7d0d6 100644
--- a/test/helper.rb
+++ b/test/helper.rb
@@ -16,6 +16,15 @@ if ENV.delete('COVERAGE')
 end
 
 $:.unshift(File.expand_path('../lib', __dir__))
-require_relative '../lib/rack'
+if ENV['SEPARATE']
+  def self.separate_testing
+    yield
+  end
+else
+  require_relative '../lib/rack'
+
+  def self.separate_testing
+  end
+end
 require 'minitest/global_expectations/autorun'
 require 'stringio'
diff --git a/test/psych_fix.rb b/test/psych_fix.rb
new file mode 100644
index 00000000..ef8a5be3
--- /dev/null
+++ b/test/psych_fix.rb
@@ -0,0 +1,8 @@
+# Work correctly with older versions of Psych, having
+# unsafe_load call load (in older versions, load operates
+# as unsafe_load in current version).
+unless YAML.respond_to?(:unsafe_load)
+  def YAML.unsafe_load(body)
+    load(body)
+  end
+end
diff --git a/test/spec_auth_basic.rb b/test/spec_auth_basic.rb
index 7d39b195..5373897c 100644
--- a/test/spec_auth_basic.rb
+++ b/test/spec_auth_basic.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/auth/basic'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/lint'
+end
+
 describe Rack::Auth::Basic do
   def realm
     'WallysWorld'
diff --git a/test/spec_auth_digest.rb b/test/spec_auth_digest.rb
index 6e32152f..6ed1f21e 100644
--- a/test/spec_auth_digest.rb
+++ b/test/spec_auth_digest.rb
@@ -2,6 +2,16 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/auth/digest/md5'
+  require_relative '../lib/rack/auth/digest/nonce'
+  require_relative '../lib/rack/auth/digest/params'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/urlmap'
+  require_relative '../lib/rack/method_override'
+end
+
 describe Rack::Auth::Digest::MD5 do
   def realm
     'WallysWorld'
diff --git a/test/spec_body_proxy.rb b/test/spec_body_proxy.rb
index 1199f2f1..91fcbd74 100644
--- a/test/spec_body_proxy.rb
+++ b/test/spec_body_proxy.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/body_proxy'
+end
+
 describe Rack::BodyProxy do
   it 'call each on the wrapped body' do
     called = false
diff --git a/test/spec_builder.rb b/test/spec_builder.rb
index eb13a976..078c0f08 100644
--- a/test/spec_builder.rb
+++ b/test/spec_builder.rb
@@ -2,6 +2,15 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/builder'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/content_length'
+  require_relative '../lib/rack/show_exceptions'
+  require_relative '../lib/rack/auth/basic'
+end
+
 class NothingMiddleware
   def initialize(app, **)
     @app = app
diff --git a/test/spec_cascade.rb b/test/spec_cascade.rb
index 8f1fd131..b2529e0e 100644
--- a/test/spec_cascade.rb
+++ b/test/spec_cascade.rb
@@ -2,6 +2,14 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/cascade'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/urlmap'
+  require_relative '../lib/rack/files'
+end
+
 describe Rack::Cascade do
   def cascade(*args)
     Rack::Lint.new Rack::Cascade.new(*args)
diff --git a/test/spec_chunked.rb b/test/spec_chunked.rb
index ceb7bdfb..2c537001 100644
--- a/test/spec_chunked.rb
+++ b/test/spec_chunked.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/chunked'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Chunked do
   def chunked(app)
     proc do |env|
diff --git a/test/spec_common_logger.rb b/test/spec_common_logger.rb
index dd55c2f8..8a572cbb 100644
--- a/test/spec_common_logger.rb
+++ b/test/spec_common_logger.rb
@@ -3,6 +3,12 @@
 require_relative 'helper'
 require 'logger'
 
+separate_testing do
+  require_relative '../lib/rack/common_logger'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::CommonLogger do
   obj = 'foobar'
   length = obj.size
diff --git a/test/spec_conditional_get.rb b/test/spec_conditional_get.rb
index 5d517be4..6ab69721 100644
--- a/test/spec_conditional_get.rb
+++ b/test/spec_conditional_get.rb
@@ -3,6 +3,12 @@
 require_relative 'helper'
 require 'time'
 
+separate_testing do
+  require_relative '../lib/rack/conditional_get'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::ConditionalGet do
   def conditional_get(app)
     Rack::Lint.new Rack::ConditionalGet.new(app)
diff --git a/test/spec_config.rb b/test/spec_config.rb
index 304ef8bf..531077d1 100644
--- a/test/spec_config.rb
+++ b/test/spec_config.rb
@@ -2,6 +2,13 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/config'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/builder'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Config do
   it "accept a block that modifies the environment" do
     app = Rack::Builder.new do
diff --git a/test/spec_content_length.rb b/test/spec_content_length.rb
index 4301b89b..a3a5995c 100644
--- a/test/spec_content_length.rb
+++ b/test/spec_content_length.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/content_length'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::ContentLength do
   def content_length(app)
     Rack::Lint.new Rack::ContentLength.new(app)
diff --git a/test/spec_content_type.rb b/test/spec_content_type.rb
index a11d2c9d..93006b06 100644
--- a/test/spec_content_type.rb
+++ b/test/spec_content_type.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/content_type'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::ContentType do
   def content_type(app, *args)
     Rack::Lint.new Rack::ContentType.new(app, *args)
diff --git a/test/spec_deflater.rb b/test/spec_deflater.rb
index ed9cffec..2eb60bd9 100644
--- a/test/spec_deflater.rb
+++ b/test/spec_deflater.rb
@@ -4,6 +4,12 @@ require_relative 'helper'
 require 'time'  # for Time#httpdate
 require 'zlib'
 
+separate_testing do
+  require_relative '../lib/rack/deflater'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Deflater do
 
   def build_response(status, body, accept_encoding, options = {})
diff --git a/test/spec_directory.rb b/test/spec_directory.rb
index 97cbadbf..9e46e896 100644
--- a/test/spec_directory.rb
+++ b/test/spec_directory.rb
@@ -4,6 +4,14 @@ require_relative 'helper'
 require 'tempfile'
 require 'fileutils'
 
+separate_testing do
+  require_relative '../lib/rack/directory'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/utils'
+  require_relative '../lib/rack/builder'
+end
+
 describe Rack::Directory do
   DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
   FILE_CATCH = proc{|env| [200, { 'Content-Type' => 'text/plain', "Content-Length" => "7" }, ['passed!']] }
diff --git a/test/spec_etag.rb b/test/spec_etag.rb
index 3528b4fa..09c5636c 100644
--- a/test/spec_etag.rb
+++ b/test/spec_etag.rb
@@ -3,6 +3,12 @@
 require_relative 'helper'
 require 'time'
 
+separate_testing do
+  require_relative '../lib/rack/etag'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::ETag do
   def etag(app, *args)
     Rack::Lint.new Rack::ETag.new(app, *args)
diff --git a/test/spec_events.rb b/test/spec_events.rb
index e2077984..3e99e35f 100644
--- a/test/spec_events.rb
+++ b/test/spec_events.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/events'
+end
+
 module Rack
   class TestEvents < Minitest::Test
     class EventMiddleware
diff --git a/test/spec_files.rb b/test/spec_files.rb
index f8d11b0b..5dfb8c6e 100644
--- a/test/spec_files.rb
+++ b/test/spec_files.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/files'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Files do
   DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
 
diff --git a/test/spec_handler.rb b/test/spec_handler.rb
index d6d9ccce..f307d158 100644
--- a/test/spec_handler.rb
+++ b/test/spec_handler.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/handler'
+end
+
 class Rack::Handler::Lobster; end
 class RockLobster; end
 
diff --git a/test/spec_head.rb b/test/spec_head.rb
index d2dedd28..0f0eb0c3 100644
--- a/test/spec_head.rb
+++ b/test/spec_head.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/head'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Head do
 
   def test_response(headers = {})
diff --git a/test/spec_lint.rb b/test/spec_lint.rb
index d822f985..17c3f150 100755
--- a/test/spec_lint.rb
+++ b/test/spec_lint.rb
@@ -3,6 +3,11 @@
 require_relative 'helper'
 require 'tempfile'
 
+separate_testing do
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Lint do
   def env(*args)
     Rack::MockRequest.env_for("/", *args)
diff --git a/test/spec_lobster.rb b/test/spec_lobster.rb
index ac3f1193..71584d4b 100644
--- a/test/spec_lobster.rb
+++ b/test/spec_lobster.rb
@@ -1,7 +1,12 @@
 # frozen_string_literal: true
 
 require_relative 'helper'
-require 'rack/lobster'
+
+require_relative '../lib/rack/lobster'
+separate_testing do
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
 
 module LobsterHelpers
   def lobster
diff --git a/test/spec_lock.rb b/test/spec_lock.rb
index c86d5b09..93695dc1 100644
--- a/test/spec_lock.rb
+++ b/test/spec_lock.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/lock'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/lint'
+end
+
 class Lock
   attr_reader :synchronized
 
diff --git a/test/spec_logger.rb b/test/spec_logger.rb
index 8355fc82..6f63f1ae 100644
--- a/test/spec_logger.rb
+++ b/test/spec_logger.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/logger'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Logger do
   app = lambda { |env|
     log = env['rack.logger']
diff --git a/test/spec_media_type.rb b/test/spec_media_type.rb
index a00a767e..1e701f25 100644
--- a/test/spec_media_type.rb
+++ b/test/spec_media_type.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/media_type'
+end
+
 describe Rack::MediaType do
   before { @empty_hash = {} }
 
diff --git a/test/spec_method_override.rb b/test/spec_method_override.rb
index 5909907b..199462db 100644
--- a/test/spec_method_override.rb
+++ b/test/spec_method_override.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/method_override'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::MethodOverride do
   def app
     Rack::Lint.new(Rack::MethodOverride.new(lambda {|e|
diff --git a/test/spec_mime.rb b/test/spec_mime.rb
index 65a77f6f..4a8ff7c9 100644
--- a/test/spec_mime.rb
+++ b/test/spec_mime.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/mime'
+end
+
 describe Rack::Mime do
 
   it "should return the fallback mime-type for files with no extension" do
diff --git a/test/spec_mock.rb b/test/spec_mock.rb
index e81f8d83..072cc352 100644
--- a/test/spec_mock.rb
+++ b/test/spec_mock.rb
@@ -2,14 +2,16 @@
 
 require_relative 'helper'
 require 'yaml'
-
-# Work correctly with older versions of Psych, having
-# unsafe_load call load (in older versions, load operates
-# as unsafe_load in current version).
-unless YAML.respond_to?(:unsafe_load)
-  def YAML.unsafe_load(body)
-    load(body)
-  end
+require_relative 'psych_fix'
+
+separate_testing do
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/request'
+  require_relative '../lib/rack/response'
+  require_relative '../lib/rack/multipart'
+  require_relative '../lib/rack/constants'
+  require_relative '../lib/rack/body_proxy'
 end
 
 app = Rack::Lint.new(lambda { |env|
diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb
index 87902a1f..ad7c1ca5 100644
--- a/test/spec_multipart.rb
+++ b/test/spec_multipart.rb
@@ -3,6 +3,14 @@
 require_relative 'helper'
 require 'timeout'
 
+separate_testing do
+  require_relative '../lib/rack/multipart'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/query_parser'
+  require_relative '../lib/rack/utils'
+end
+
 describe Rack::Multipart do
   def multipart_fixture(name, boundary = "AaB03x")
     file = multipart_file(name)
diff --git a/test/spec_null_logger.rb b/test/spec_null_logger.rb
index 435d051e..8659a8e5 100644
--- a/test/spec_null_logger.rb
+++ b/test/spec_null_logger.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/null_logger'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::NullLogger do
   it "act as a noop logger" do
     app = lambda { |env|
diff --git a/test/spec_recursive.rb b/test/spec_recursive.rb
index 62e3a4f1..1691066e 100644
--- a/test/spec_recursive.rb
+++ b/test/spec_recursive.rb
@@ -2,6 +2,13 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/recursive'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/urlmap'
+end
+
 describe Rack::Recursive do
   before do
   @app1 = lambda { |env|
diff --git a/test/spec_request.rb b/test/spec_request.rb
index d0b0df34..79b612a9 100644
--- a/test/spec_request.rb
+++ b/test/spec_request.rb
@@ -5,6 +5,12 @@ require 'cgi'
 require 'forwardable'
 require 'securerandom'
 
+separate_testing do
+  require_relative '../lib/rack/request'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/lint'
+end
+
 class RackRequestTest < Minitest::Spec
   it "copies the env when duping" do
     req = make_request(Rack::MockRequest.env_for("http://example.com:8080/"))
diff --git a/test/spec_response.rb b/test/spec_response.rb
index 1dfafcdb..3c25aa0c 100644
--- a/test/spec_response.rb
+++ b/test/spec_response.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/response'
+end
+
 describe Rack::Response do
   it 'has standard constructor' do
     headers = { "header" => "value" }
diff --git a/test/spec_rewindable_input.rb b/test/spec_rewindable_input.rb
index 1ea84841..5c1bf5c9 100644
--- a/test/spec_rewindable_input.rb
+++ b/test/spec_rewindable_input.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/rewindable_input'
+end
+
 module RewindableTest
   extend Minitest::Spec::DSL
 
diff --git a/test/spec_runtime.rb b/test/spec_runtime.rb
index e4fc3f95..0b927e9a 100644
--- a/test/spec_runtime.rb
+++ b/test/spec_runtime.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/runtime'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Runtime do
   def runtime_app(app, *args)
     Rack::Lint.new Rack::Runtime.new(app, *args)
diff --git a/test/spec_sendfile.rb b/test/spec_sendfile.rb
index 09e810e9..f69a3e41 100644
--- a/test/spec_sendfile.rb
+++ b/test/spec_sendfile.rb
@@ -4,6 +4,12 @@ require_relative 'helper'
 require 'fileutils'
 require 'tmpdir'
 
+separate_testing do
+  require_relative '../lib/rack/sendfile'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Sendfile do
   def sendfile_body(filename = "rack_sendfile")
     FileUtils.touch File.join(Dir.tmpdir,  filename)
diff --git a/test/spec_server.rb b/test/spec_server.rb
index 48b1cabb..1e2d7cfa 100644
--- a/test/spec_server.rb
+++ b/test/spec_server.rb
@@ -8,7 +8,15 @@ require 'open-uri'
 require 'net/http'
 require 'net/https'
 
-require 'rack/handler/cgi'
+separate_testing do
+  require_relative '../lib/rack/server'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/show_exceptions'
+  require_relative '../lib/rack/tempfile_reaper'
+  require_relative '../lib/rack/handler'
+  require_relative '../lib/rack/handler/cgi'
+end
 
 module Minitest::Spec::DSL
   alias :should :it
diff --git a/test/spec_session_abstract_id.rb b/test/spec_session_abstract_id.rb
index 17cdb3e5..9812b530 100644
--- a/test/spec_session_abstract_id.rb
+++ b/test/spec_session_abstract_id.rb
@@ -3,7 +3,10 @@
 require_relative 'helper'
 ### WARNING: there be hax in this file.
 
-require 'rack/session/abstract/id'
+require_relative '../lib/rack/session/abstract/id'
+separate_testing do
+  require_relative '../lib/rack/request'
+end
 
 describe Rack::Session::Abstract::ID do
   attr_reader :id
diff --git a/test/spec_session_abstract_persisted.rb b/test/spec_session_abstract_persisted.rb
index 84ddf072..1b1fce86 100644
--- a/test/spec_session_abstract_persisted.rb
+++ b/test/spec_session_abstract_persisted.rb
@@ -1,7 +1,11 @@
 # frozen_string_literal: true
 
 require_relative 'helper'
-require 'rack/session/abstract/id'
+
+require_relative '../lib/rack/session/abstract/id'
+separate_testing do
+  require_relative '../lib/rack/request'
+end
 
 describe Rack::Session::Abstract::Persisted do
   def setup
diff --git a/test/spec_session_abstract_persisted_secure_secure_session_hash.rb b/test/spec_session_abstract_persisted_secure_secure_session_hash.rb
index bbb8a900..d6d18860 100644
--- a/test/spec_session_abstract_persisted_secure_secure_session_hash.rb
+++ b/test/spec_session_abstract_persisted_secure_secure_session_hash.rb
@@ -1,7 +1,11 @@
 # frozen_string_literal: true
 
 require_relative 'helper'
-require 'rack/session/abstract/id'
+require_relative '../lib/rack/session/abstract/id'
+
+separate_testing do
+  require_relative '../lib/rack/request'
+end
 
 describe Rack::Session::Abstract::PersistedSecure::SecureSessionHash do
   attr_reader :hash
diff --git a/test/spec_session_abstract_session_hash.rb b/test/spec_session_abstract_session_hash.rb
index ac0b7bb3..2a832c1c 100644
--- a/test/spec_session_abstract_session_hash.rb
+++ b/test/spec_session_abstract_session_hash.rb
@@ -1,7 +1,11 @@
 # frozen_string_literal: true
 
 require_relative 'helper'
+
 require 'rack/session/abstract/id'
+separate_testing do
+  require_relative '../lib/rack/request'
+end
 
 describe Rack::Session::Abstract::SessionHash do
   attr_reader :hash
diff --git a/test/spec_session_cookie.rb b/test/spec_session_cookie.rb
index 875c883e..5993dc01 100644
--- a/test/spec_session_cookie.rb
+++ b/test/spec_session_cookie.rb
@@ -2,6 +2,13 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/session/cookie'
+  require_relative '../lib/rack/response'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::Session::Cookie do
   incrementor = lambda do |env|
     env["rack.session"]["counter"] ||= 0
diff --git a/test/spec_session_pool.rb b/test/spec_session_pool.rb
index a8e1f3da..02b196d3 100644
--- a/test/spec_session_pool.rb
+++ b/test/spec_session_pool.rb
@@ -2,6 +2,14 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/session/pool'
+  require_relative '../lib/rack/response'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/utils'
+end
+
 describe Rack::Session::Pool do
   session_key = Rack::Session::Pool::DEFAULT_OPTIONS[:key]
   session_match = /#{session_key}=([0-9a-fA-F]+);/
diff --git a/test/spec_show_exceptions.rb b/test/spec_show_exceptions.rb
index 441599b4..d0fdf0fd 100644
--- a/test/spec_show_exceptions.rb
+++ b/test/spec_show_exceptions.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/show_exceptions'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::ShowExceptions do
   def show_exceptions(app)
     Rack::Lint.new Rack::ShowExceptions.new(app)
diff --git a/test/spec_show_status.rb b/test/spec_show_status.rb
index c5784b16..e8d88b41 100644
--- a/test/spec_show_status.rb
+++ b/test/spec_show_status.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/show_status'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::ShowStatus do
   def show_status(app)
     Rack::Lint.new Rack::ShowStatus.new(app)
diff --git a/test/spec_static.rb b/test/spec_static.rb
index 2a94d68c..b8c02b1f 100644
--- a/test/spec_static.rb
+++ b/test/spec_static.rb
@@ -3,6 +3,12 @@
 require_relative 'helper'
 require 'zlib'
 
+separate_testing do
+  require_relative '../lib/rack/static'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 class DummyApp
   def call(env)
     [200, { "Content-Type" => "text/plain" }, ["Hello World"]]
diff --git a/test/spec_tempfile_reaper.rb b/test/spec_tempfile_reaper.rb
index 4756e53e..ce5d2c76 100644
--- a/test/spec_tempfile_reaper.rb
+++ b/test/spec_tempfile_reaper.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/tempfile_reaper'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::TempfileReaper do
   class MockTempfile
     attr_reader :closed
diff --git a/test/spec_urlmap.rb b/test/spec_urlmap.rb
index 29af5587..db3c676a 100644
--- a/test/spec_urlmap.rb
+++ b/test/spec_urlmap.rb
@@ -2,6 +2,12 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/urlmap'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+end
+
 describe Rack::URLMap do
   it "dispatches paths correctly" do
     app = lambda { |env|
diff --git a/test/spec_utils.rb b/test/spec_utils.rb
index b2d75f27..e588970b 100644
--- a/test/spec_utils.rb
+++ b/test/spec_utils.rb
@@ -3,6 +3,14 @@
 require_relative 'helper'
 require 'timeout'
 
+separate_testing do
+  require_relative '../lib/rack/utils'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/mock'
+  require_relative '../lib/rack/request'
+  require_relative '../lib/rack/content_length'
+end
+
 describe Rack::Utils do
 
   def assert_sets(exp, act)
diff --git a/test/spec_version.rb b/test/spec_version.rb
index 68c4b4c7..d9be54d2 100644
--- a/test/spec_version.rb
+++ b/test/spec_version.rb
@@ -2,6 +2,10 @@
 
 require_relative 'helper'
 
+separate_testing do
+  require_relative '../lib/rack/version'
+end
+
 describe Rack do
   describe 'version' do
     it 'defaults to a hard-coded api version' do
diff --git a/test/spec_webrick.rb b/test/spec_webrick.rb
index ffb03740..96f86c25 100644
--- a/test/spec_webrick.rb
+++ b/test/spec_webrick.rb
@@ -2,8 +2,15 @@
 
 require_relative 'helper'
 require 'thread'
+require 'webrick'
 require_relative 'test_request'
 
+separate_testing do
+  require_relative '../lib/rack/handler'
+  require_relative '../lib/rack/lint'
+  require_relative '../lib/rack/response'
+end
+
 Thread.abort_on_exception = true
 
 describe Rack::Handler::WEBrick do
diff --git a/test/test_request.rb b/test/test_request.rb
index ae995c53..23beecf7 100644
--- a/test/test_request.rb
+++ b/test/test_request.rb
@@ -1,6 +1,7 @@
 # frozen_string_literal: true
 
 require 'yaml'
+require_relative 'psych_fix'
 require 'net/http'
 require 'rack/lint'