Skip to content

🔊 Add config option for responses_without_block #293

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

Merged
merged 2 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2501,6 +2501,7 @@ def idle_done
#
# Calling without a block is unsafe and deprecated. Future releases will
# raise ArgumentError unless a block is given.
# See Config#responses_without_block.
#
# Previously unhandled responses are automatically cleared before entering a
# mailbox with #select or #examine. Long-lived connections can receive many
Expand All @@ -2525,7 +2526,12 @@ def responses(type = nil)
elsif type
raise ArgumentError, "Pass a block or use #clear_responses"
else
# warn("DEPRECATED: pass a block or use #clear_responses", uplevel: 1)
case config.responses_without_block
when :raise
raise ArgumentError, "Pass a block or use #clear_responses"
when :warn
warn("DEPRECATED: pass a block or use #clear_responses", uplevel: 1)
end
@responses
end
end
Expand Down
16 changes: 16 additions & 0 deletions lib/net/imap/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,21 @@ def self.[](config) # :nodoc: unfinished API
# | v0.4 | +true+ <em>(support added)</em> |
attr_accessor :sasl_ir, type: :boolean

# :markup: markdown
#
# Controls the behavior of Net::IMAP#responses when called without a
# block. Valid options are `:warn`, `:raise`, or
# `:silence_deprecation_warning`.
#
# | Starting with version | The default value is |
# |-----------------------|--------------------------------|
# | v0.4.13 | +:silence_deprecation_warning+ |
# | v0.5 | +:warn+ |
# | _eventually_ | +:raise+ |
attr_accessor :responses_without_block, type: [
:silence_deprecation_warning, :warn, :raise,
]

# Creates a new config object and initialize its attribute with +attrs+.
#
# If +parent+ is not given, the global config is used by default.
Expand All @@ -130,6 +145,7 @@ def initialize(parent = Config.global, **attrs)
open_timeout: 30,
idle_response_timeout: 5,
sasl_ir: true,
responses_without_block: :silence_deprecation_warning,
).freeze

@global = default.new
Expand Down
12 changes: 12 additions & 0 deletions lib/net/imap/config/attr_type_coercion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def self.attr_accessor(attr, type: nil)
return unless type
if :boolean == type then boolean attr
elsif Integer == type then integer attr
elsif Array === type then enum attr, type
else raise ArgumentError, "unknown type coercion %p" % [type]
end
end
Expand All @@ -39,6 +40,17 @@ def self.integer(attr)
define_method :"#{attr}=" do |val| super Integer val end
end

def self.enum(attr, enum)
enum = enum.dup.freeze
expected = -"one of #{enum.map(&:inspect).join(", ")}"
define_method :"#{attr}=" do |val|
unless enum.include?(val)
raise ArgumentError, "expected %s, got %p" % [expected, val]
end
super val
end
end

end
end
end
Expand Down
16 changes: 16 additions & 0 deletions test/net/imap/test_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ class ConfigTest < Test::Unit::TestCase
assert_equal 333, config.open_timeout
end

test "enum type constraint" do
config = Config.new
config.responses_without_block = :silence_deprecation_warning
assert_equal :silence_deprecation_warning, config.responses_without_block
config.responses_without_block = :warn
assert_equal :warn, config.responses_without_block
config.responses_without_block = :raise
assert_equal :raise, config.responses_without_block
assert_raise(ArgumentError) do config.responses_without_block = false end
assert_equal :raise, config.responses_without_block
assert_raise(ArgumentError) do config.responses_without_block = 12345 end
assert_equal :raise, config.responses_without_block
assert_raise(ArgumentError) do config.responses_without_block = "warn" end
assert_equal :raise, config.responses_without_block
end

test ".default" do
default = Config.default
assert default.equal?(Config.default)
Expand Down
20 changes: 16 additions & 4 deletions test/net/imap/test_imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1122,10 +1122,22 @@ def test_responses
assert_equal(1, imap.responses("RECENT", &:last))
assert_raise(ArgumentError) do imap.responses("UIDNEXT") end
# Deprecated style, without a block:
# assert_warn(/Pass a block.*or.*clear_responses/i) do
# assert_equal(%i[Answered Flagged Deleted Seen Draft],
# imap.responses["FLAGS"]&.last)
# end
imap.config.responses_without_block = :raise
assert_raise(ArgumentError) do imap.responses end
imap.config.responses_without_block = :warn
assert_raise(ArgumentError) do imap.responses("UIDNEXT") end
assert_warn(/Pass a block.*or.*clear_responses/i) do
assert_equal(%i[Answered Flagged Deleted Seen Draft],
imap.responses["FLAGS"]&.last)
end
# TODO: assert_no_warn?
imap.config.responses_without_block = :silence_deprecation_warning
assert_raise(ArgumentError) do imap.responses("UIDNEXT") end
stderr = EnvUtil.verbose_warning {
assert_equal(%i[Answered Flagged Deleted Seen Draft],
imap.responses["FLAGS"]&.last)
}
assert_empty stderr
end
end

Expand Down