From eabd5509d0c936759b82260d1e516425c020e880 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Fri, 11 Apr 2025 17:34:02 +0200 Subject: [PATCH] demonstrate bug: service provides array_of_hashes but misdeclares as a{sv} This is an easy to make mistake because the spec unhelpfully exposes the wire format and works with arrays of dictionary entries instead of with hashes --- lib/dbus/data.rb | 3 +++ lib/dbus/type.rb | 2 +- spec/mock-service/spaghetti-monster.rb | 6 ++++++ spec/property_spec.rb | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/dbus/data.rb b/lib/dbus/data.rb index da8d5ec..8fa44c2 100644 --- a/lib/dbus/data.rb +++ b/lib/dbus/data.rb @@ -44,6 +44,9 @@ def make_typed(type, value) # not nil because DBus.type validates data_class.from_typed(value, type: type) + rescue StandardError => e + msg = "When making #{type.inspect} from an instance of #{value.class}: " + e.message + raise e.exception(msg) end module_function :make_typed diff --git a/lib/dbus/type.rb b/lib/dbus/type.rb index 4941605..ab1238f 100644 --- a/lib/dbus/type.rb +++ b/lib/dbus/type.rb @@ -363,7 +363,7 @@ def self.[](key_type, value_type) end # @example - # t = Type::Hash[Type::INT16] + # t = Type::Hash[Type::STRING, Type::VARIANT] Hash = HashFactory # Syntactic helper for constructing a struct Type. diff --git a/spec/mock-service/spaghetti-monster.rb b/spec/mock-service/spaghetti-monster.rb index f925374..50ee59f 100755 --- a/spec/mock-service/spaghetti-monster.rb +++ b/spec/mock-service/spaghetti-monster.rb @@ -46,6 +46,10 @@ def initialize(path) "two" => "dva", "three" => [3, 3, 3] } + # reproduce bug: + # type mismatch (user means to declare array_of_hashes as aa{sv}) + # should produce informative error + @array_of_hashes = [@my_dict.dup] @my_variant = @my_array.dup # 201 is a RET instruction for ZX Spectrum which has turned 40 recently @my_byte = 201 @@ -140,6 +144,8 @@ def explosive dbus_attr_accessor :my_array, "aq" dbus_attr_accessor :my_dict, "a{sv}" dbus_attr_accessor :my_variant, "v" + # intentional bug to test reporting it: declaring an array of dict-entries instead + dbus_attr_reader :array_of_hashes, "a{sv}" dbus_attr_accessor :my_byte, "y" diff --git a/spec/property_spec.rb b/spec/property_spec.rb index 372dea4..60ded74 100755 --- a/spec/property_spec.rb +++ b/spec/property_spec.rb @@ -179,6 +179,20 @@ val = @iface["MyArray"] expect(val).to eq([42, 43]) end + + it "a wrongly typed property provides a helpful message" do + # Now we get: + # When getting 'org.ruby.SampleInterface.ArrayOfHashes': + # When making ARRAY: [DICT_ENTRY: [STRING, VARIANT]] from an instance of Array: + # When making DICT_ENTRY: [STRING, VARIANT] from an instance of Hash: + # Specified type has 2 members but value has 3 members; + # caused by 1 sender=:1.70... + # But we should really say + # When making HASH: [STRING, VARIANT] from an instance of Array + # and document better this pitfall. + # Do we want to quote the entire data? + expect { @iface["ArrayOfHashes"] }.to raise_error(/DWIM/) + end end context "a dict-typed property" do