diff --git a/lib/net/imap.rb b/lib/net/imap.rb index c94e236a..3adb2d7f 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -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 @@ -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 diff --git a/lib/net/imap/config.rb b/lib/net/imap/config.rb index 4194936a..f2909ac2 100644 --- a/lib/net/imap/config.rb +++ b/lib/net/imap/config.rb @@ -114,6 +114,21 @@ def self.[](config) # :nodoc: unfinished API # | v0.4 | +true+ (support added) | 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. @@ -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 diff --git a/lib/net/imap/config/attr_type_coercion.rb b/lib/net/imap/config/attr_type_coercion.rb index 7511193d..51fd8ffd 100644 --- a/lib/net/imap/config/attr_type_coercion.rb +++ b/lib/net/imap/config/attr_type_coercion.rb @@ -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 @@ -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 diff --git a/test/net/imap/test_config.rb b/test/net/imap/test_config.rb index e14d7b74..1b97813f 100644 --- a/test/net/imap/test_config.rb +++ b/test/net/imap/test_config.rb @@ -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) diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb index ff8c3109..558e7e0f 100644 --- a/test/net/imap/test_imap.rb +++ b/test/net/imap/test_imap.rb @@ -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