Skip to content

Commit 8e6b42a

Browse files
committed
🚧 Check if the Data implementation is sufficient
1 parent bb8b222 commit 8e6b42a

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

lib/net/imap/data_lite.rb

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,54 @@
2626

2727
module Net
2828
class IMAP
29-
data_or_object =
30-
if RUBY_VERSION >= "3.2.0" && defined?(::Data) && ::Data.respond_to?(:define)
31-
::Data
32-
else
33-
Object
29+
30+
# :nocov:
31+
# Skip coverage: how much of the file runs depends on the engine version.
32+
33+
# Test whether RUBY_ENGINE has sufficient support for ::Data.
34+
# TODO: golf this down to the bare minimum that's failing.
35+
data_or_object = ::Object
36+
if defined?(::Data) && ::Data.respond_to?(:define)
37+
begin
38+
class TestData < ::Data
39+
def self.YAML(data)
40+
coder = Struct.new(:map).new(data)
41+
data = self.allocate
42+
data.init_with(coder)
43+
data
44+
end
45+
def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
46+
def deconstruct; [:ok, *super] end
47+
end
48+
49+
class TestDataDefine < TestData.define(:str, :bool)
50+
def initialize(str: nil, bool: nil)
51+
str => String | nil; str = -str if str
52+
bool => true | false | nil; bool = !!bool
53+
super
54+
end
55+
end
56+
57+
test_init = TestDataDefine.YAML({"str" => "str"})
58+
test_empty = TestData.define[]
59+
60+
if test_init.deconstruct != [:ok, "str", false]
61+
raise "subclassing misbehaves"
62+
elsif test_empty.deconstruct != [:ok]
63+
raise "can't define empty"
64+
end
65+
data_or_object = ::Data
66+
rescue => ex
67+
warn "Insufficient implementation of Data: %s (%s) for %s %s" % [
68+
ex, ex.class, RUBY_ENGINE, RUBY_ENGINE_VERSION,
69+
]
70+
data_or_object = ::Object
71+
ensure
72+
remove_const :TestData if const_defined?(:TestData)
73+
remove_const :TestDataDefine if const_defined?(:TestDataDefine)
3474
end
75+
end
76+
3577
class DataLite < data_or_object
3678
def encode_with(coder) coder.map = to_h.transform_keys(&:to_s) end
3779
def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
@@ -41,9 +83,7 @@ def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
4183
end
4284
end
4385

44-
# :nocov:
45-
# Need to skip test coverage for the rest, because it isn't loaded by ruby 3.2+.
46-
return if RUBY_VERSION >= "3.2.0" && defined?(::Data) && ::Data.respond_to?(:define)
86+
return unless Net::IMAP::DataLite.superclass == Object
4787

4888
module Net
4989
class IMAP

0 commit comments

Comments
 (0)