Skip to content

Commit c88765d

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

File tree

1 file changed

+45
-6
lines changed

1 file changed

+45
-6
lines changed

lib/net/imap/data_lite.rb

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,51 @@
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+
# Test whether RUBY_ENGINE has sufficient support for ::Data.
31+
# TODO: golf this down to the bare minimum that's failing.
32+
data_or_object = ::Object
33+
if defined?(::Data) && ::Data.respond_to?(:define)
34+
begin
35+
class TestData < ::Data
36+
def self.YAML(data)
37+
coder = Struct.new(:map).new(data)
38+
data = self.allocate
39+
data.init_with(coder)
40+
data
41+
end
42+
def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
43+
def deconstruct; [:ok, *super] end
44+
end
45+
46+
class TestDataDefine < TestData.define(:str, :bool)
47+
def initialize(str: nil, bool: nil)
48+
str => String | nil; str = -str if str
49+
bool => true | false | nil; bool = !!bool
50+
super
51+
end
52+
end
53+
54+
test_init = TestDataDefine.YAML({"str" => "str"})
55+
test_empty = TestData.define[]
56+
57+
if test_init.deconstruct != [:ok, "str", false]
58+
raise "subclassing misbehaves"
59+
elsif test_empty.deconstruct != [:ok]
60+
raise "can't define empty"
61+
end
62+
data_or_object = ::Data
63+
rescue => ex
64+
warn "Insufficient implementation of Data: %s (%s) for %s %s" % [
65+
ex, ex.class, RUBY_ENGINE, RUBY_ENGINE_VERSION,
66+
]
67+
data_or_object = ::Object
68+
ensure
69+
remove_const :TestData if const_defined?(:TestData)
70+
remove_const :TestDataDefine if const_defined?(:TestDataDefine)
3471
end
72+
end
73+
3574
class DataLite < data_or_object
3675
def encode_with(coder) coder.map = to_h.transform_keys(&:to_s) end
3776
def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
@@ -43,7 +82,7 @@ def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
4382

4483
# :nocov:
4584
# 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)
85+
return unless Net::IMAP::DataLite.superclass == Object
4786

4887
module Net
4988
class IMAP

0 commit comments

Comments
 (0)