-
Notifications
You must be signed in to change notification settings - Fork 251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add Rack::Test.default_host= to change the default_host more easily. #317
Conversation
@@ -30,7 +30,14 @@ module Rack | |||
module Test | |||
# The default host to use for requests, when a full URI is not | |||
# provided. | |||
DEFAULT_HOST = 'example.org'.freeze | |||
def self.default_host |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could maybe leave in the constant DEFAULT_HOST for people using a work around?
@@ -30,7 +30,14 @@ module Rack | |||
module Test | |||
# The default host to use for requests, when a full URI is not | |||
# provided. | |||
DEFAULT_HOST = 'example.org'.freeze | |||
def self.default_host | |||
@@default_host ||= 'example.org'.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we consider the following implementation:
DEFAULT_HOST = 'example.org'.freeze
class << self
@default_host = DEFAULT_HOST
attr_accessor :default_host
end
I'm not sure if we can remove DEFAULT_HOST
.
Consider that ||=
isn't thread safe and we could in theory have multiple threads accessing this field.
We've followed this model elsewhere: https://github.com/rack/rack/blob/main/lib/rack/request.rb#L17-L41
Don't have a strong opinion about it, just wanted to make a suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely cannot accept the use of class variables. Class variables in Ruby are broken and should never be used.
This approach:
class << self
@default_host = DEFAULT_HOST
attr_accessor :default_host
end
Is broken. It sets the instance variable in the singleton class instead of the class. However, with that fixed, because Rack::Test
is a module and not a class, the approach seems acceptable (it wouldn't be acceptable for a class, but then it breaks in a subclass unless you copy the instance variable during subclassing).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah using the approach above failed 1-44 tests in a somewhat random nature. Moving to this:
@default_host = DEFAULT_HOST
class << self
attr_accessor :default_host
end
makes all the tests passing again. Since it is a module, I am not sure I see the difference.
@@ -54,7 +61,7 @@ class Session | |||
extend Forwardable | |||
include Rack::Test::Utils | |||
|
|||
def self.new(app, default_host = DEFAULT_HOST) # :nodoc: | |||
def self.new(app, default_host = Rack::Test.default_host) # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thinking about alternatives, is there no easy way to inject the default host argument on a per-test/spec basis?
What about if we made this default_host:
options and provided some kind of app_options
or something similar so you could write:
let(:app_options) {{default_host: '...'}}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think per test/spec is possible. You can override the URI provided for each request, but the CookieJar always uses the default host for the session, and Rack::Test::Methods
does not provide a way to set the default_host, without overriding build_rack_test_session
.
I think it may be better to modify build_rack_test_session
. If the current scope responds to default_host
, it calls it and uses it as the second argument. Otherwise, it continues to pass one argument (app
). That way you can allow for global, per-suite, and per-test/spec setting of default_host, with minimal change to the current implementation. That seems like a better approach to me, what do you think? If you like that approach, I can implement it.
I took a look at the code, and there are a number of constants which might benefit from this transformation. @jeremyevans what do you think about migrating all of these to https://github.com/rack/rack-test/blob/main/lib/rack/test.rb#L31-L43 This would be similar to what you did for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I'm positive to supporting this feature in some way, but negative to this approach (adding Rack::Test.default_host
).
@@ -30,7 +30,14 @@ module Rack | |||
module Test | |||
# The default host to use for requests, when a full URI is not | |||
# provided. | |||
DEFAULT_HOST = 'example.org'.freeze | |||
def self.default_host | |||
@@default_host ||= 'example.org'.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely cannot accept the use of class variables. Class variables in Ruby are broken and should never be used.
This approach:
class << self
@default_host = DEFAULT_HOST
attr_accessor :default_host
end
Is broken. It sets the instance variable in the singleton class instead of the class. However, with that fixed, because Rack::Test
is a module and not a class, the approach seems acceptable (it wouldn't be acceptable for a class, but then it breaks in a subclass unless you copy the instance variable during subclassing).
@@ -54,7 +61,7 @@ class Session | |||
extend Forwardable | |||
include Rack::Test::Utils | |||
|
|||
def self.new(app, default_host = DEFAULT_HOST) # :nodoc: | |||
def self.new(app, default_host = Rack::Test.default_host) # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think per test/spec is possible. You can override the URI provided for each request, but the CookieJar always uses the default host for the session, and Rack::Test::Methods
does not provide a way to set the default_host, without overriding build_rack_test_session
.
I think it may be better to modify build_rack_test_session
. If the current scope responds to default_host
, it calls it and uses it as the second argument. Otherwise, it continues to pass one argument (app
). That way you can allow for global, per-suite, and per-test/spec setting of default_host, with minimal change to the current implementation. That seems like a better approach to me, what do you think? If you like that approach, I can implement it.
@jeremyevans I don't fully understand why it's acceptable in In any case, maybe you can propose a good way to support this feature/functionality? |
In my comment (#317 (comment)), I stated if you changed where the variable was assigned, it would be acceptable. However, as I pointed out, I'm negative adding
I already proposed a way to get global, per suite, and per-test/spec default host: #317 (comment). What are you thoughts on that? |
@jeremyevans I'm fine to defer to your judgement on this. I'd like to fully understand the implications of the singleton_class variable so that I don't repeat the mistakes. Just so I understand, on this line: rack-test/lib/rack/test/methods.rb Line 45 in 112242e
|
This allows you to configure a default host the same way you configure the application. Fixes rack#317
This allows you to configure a default host the same way you configure the application. Fixes #317
As with the people in #15 AND #239 I was having issues setting/changing the DEFAULT_HOST.
Current work around is ugly:
My tests have to check the app changes databases based on the subdomain, so an easy way to change the default host makes my tests much easier to read.