Skip to content

Commit

Permalink
Make Data::DictEntry a subclass of Data::Struct; test DictEntry#initi…
Browse files Browse the repository at this point in the history
…alize

to share the #initialize logic
  • Loading branch information
mvidner committed May 25, 2022
1 parent 0589fe0 commit 2351007
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 26 deletions.
33 changes: 7 additions & 26 deletions lib/dbus/data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -650,15 +650,17 @@ def initialize(value, type:)
@type = type

typed_value = case value
when Data::Struct
when self.class
raise ArgumentError, "Specified type is #{type} but value type is #{value.type}" \
unless value.type == type

value.exact_value
else
member_types = type.members
raise ArgumentError, "Specified type has #{member_types.size} members but value has #{value.size} members" \
unless value.size == member_types.size
unless value.size == member_types.size
raise ArgumentError, "Specified type has #{member_types.size} members " \
"but value has #{value.size} members"
end

member_types.zip(value).map do |item_type, item|
Data.make_typed(item_type, item)
Expand All @@ -680,15 +682,11 @@ def ==(other)

# Dictionary/Hash entry.
# TODO: shouldn't instantiate?
class DictEntry < Container
class DictEntry < Struct
def self.type_code
"e"
end

def self.alignment
8
end

# @param value [::Array]
def self.from_items(value, mode:, type:) # rubocop:disable Lint/UnusedMethodArgument
value.freeze
Expand All @@ -700,24 +698,7 @@ def self.from_items(value, mode:, type:) # rubocop:disable Lint/UnusedMethodArgu
# @param type [Type]
# @return [DictEntry]
def self.from_typed(value, type:)
assert_type_matches_class(type)
member_types = type.members
# assert member_types.size == 2
# TODO: duplicated from Struct. Inherit/delegate?
# TODO: validation
raise unless value.size == member_types.size

items = member_types.zip(value).map do |item_type, item|
Data.make_typed(item_type, item)
end

new(items, type: type) # initialize(::Array<Data::Base>)
end

def initialize(value, type:)
self.class.assert_type_matches_class(type)
@type = type
super(value)
new(value, type: type)
end
end

Expand Down
59 changes: 59 additions & 0 deletions spec/data_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,65 @@
end
end

describe DBus::Data::DictEntry do
describe ".from_typed" do
it "creates new instance from given object and type" do
type = T::Hash[String, T::INT16].child
expect(described_class.from_typed(["test", 12], type: type))
.to be_a(described_class)
end
end

describe "#initialize" do
it "checks that type matches class" do
value = [1, 2]
type = T::Array[T::INT32]

expect { described_class.new(value, type: type) }
.to raise_error(ArgumentError, /Expecting "e"/)
end

it "checks type of a Data::DictEntry value" do
value1 = [1, 2]
type1 = T::Hash[T::UINT32, T::UINT32].child
result1 = described_class.new(value1, type: type1)

value2 = result1
type2 = T::Hash[T::UINT64, T::UINT64].child
expect { described_class.new(value2, type: type2) }
.to raise_error(ArgumentError, /value type is .uu./)
end

it "checks that size of type and value match" do
value = [1, 2, 3]
type = T::Hash[T::UINT32, T::UINT32].child
expect { described_class.new(value, type: type) }
.to raise_error(ArgumentError, /type has 2 members.*value has 3 members/)
end

it "converts value to ::Array of Data::Base" do
two_words = ::Struct.new(:k, :v)
value = two_words.new(1, 2)
type = T::Hash[T::UINT32, T::UINT32].child
result = described_class.new(value, type: type)

expect(result.exact_value).to be_an(::Array)
expect(result.exact_value[0]).to be_a(DBus::Data::Base)
end

it "takes a plain value" do
input = ["test", 23]

type = T::Hash[String, T::INT16].child
value = described_class.new(input, type: type)

expect(value).to be_a(described_class)
expect(value.type.to_s).to eq "{sn}"
expect(value.value).to eql input
end
end
end

describe DBus::Data::Variant do
describe ".from_typed" do
it "creates new instance from given object and type" do
Expand Down

0 comments on commit 2351007

Please sign in to comment.