From ea3a298aba95ce38b6fe7744ff570193d3ffc752 Mon Sep 17 00:00:00 2001 From: nick evans Date: Thu, 20 Jun 2024 07:29:40 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Add=20Config#with(**attrs)=20to?= =?UTF-8?q?=20make=20child=20configs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/net/imap/config.rb | 18 ++++++++++++++++++ test/net/imap/test_config.rb | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/lib/net/imap/config.rb b/lib/net/imap/config.rb index 9f1540bc0..10740ffb9 100644 --- a/lib/net/imap/config.rb +++ b/lib/net/imap/config.rb @@ -165,6 +165,24 @@ def update(**attrs) self end + # :call-seq: + # with(**attrs) -> config + # with(**attrs) {|config| } -> result + # + # Without a block, returns a new config which inherits from self. With a + # block, yields the new config and returns the block's result. + # + # If no keyword arguments are given, an ArgumentError will be raised. + # + # If +self+ is frozen, the copy will also be frozen. + def with(**attrs) + attrs.empty? and + raise ArgumentError, "expected keyword arguments, none given" + copy = new(**attrs) + copy.freeze if frozen? + block_given? ? yield(copy) : copy + end + # :call-seq: to_h -> hash # # Returns all config attributes in a hash. diff --git a/test/net/imap/test_config.rb b/test/net/imap/test_config.rb index 2e90e3ef0..d8d2ef6eb 100644 --- a/test/net/imap/test_config.rb +++ b/test/net/imap/test_config.rb @@ -212,4 +212,29 @@ class ConfigTest < Test::Unit::TestCase assert_same false, config.sasl_ir? # unchanged end + test "#with" do + orig = Config.new(open_timeout: 123, sasl_ir: false) + assert_raise(ArgumentError) do + orig.with + end + copy = orig.with(open_timeout: 456, idle_response_timeout: 789) + refute copy.frozen? + assert_same orig, copy.parent + assert_equal 123, orig.open_timeout # unchanged + assert_equal 456, copy.open_timeout + assert_equal 789, copy.idle_response_timeout + vals = nil + result = orig.with(open_timeout: 99, idle_response_timeout: 88) do |c| + vals = [c.open_timeout, c.idle_response_timeout, c.frozen?] + :result + end + assert_equal :result, result + assert_equal [99, 88, false], vals + orig.freeze + result = orig.with(open_timeout: 11) do |c| + vals = [c.open_timeout, c.idle_response_timeout, c.frozen?] + end + assert_equal [11, 5, true], vals + end + end