ruby-dbus 0.18.0.beta5 → 0.18.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NEWS.md +11 -0
- data/VERSION +1 -1
- data/lib/dbus/data.rb +136 -73
- data/lib/dbus/marshall.rb +6 -3
- data/lib/dbus/type.rb +24 -1
- data/spec/data_spec.rb +300 -8
- data/spec/packet_unmarshaller_spec.rb +2 -16
- data/spec/type_spec.rb +40 -0
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54a45385340217271e3fb445cddf6afcddb9892c4bf75b503e7859390f4d2ed7
|
4
|
+
data.tar.gz: 3c4f71745992c5afece87e34909e67f451717c9398ac6efb6235cc64ad1d1b0c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 864aaaaa867ea04247515d875d836560a558b7a3d780712a41dcd52214d95e47e857d640d66a3573eaf4df778a0320f89ad2c59918c005a2fc80adb8a63074cb
|
7
|
+
data.tar.gz: cabd9d699d8b7aad7c5f77a83aa07389b59c11b34b1219822909a031774b078d0bf001a1bce9bb5912be42caa4adba7608906ebc76dde57ff9f06d13afd7850f
|
data/NEWS.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## Ruby D-Bus 0.18.0.beta6 - 2022-05-25
|
6
|
+
|
7
|
+
API:
|
8
|
+
* Data::Base#value returns plain Ruby types;
|
9
|
+
Data::Container#exact_value contains Data::Base ([#114][]).
|
10
|
+
* Data::Base#initialize and .from_typed allow plain or exact values, validate
|
11
|
+
argument types.
|
12
|
+
* Implement #== (converting) and #eql? (strict) for Data::Base and DBus::Type.
|
13
|
+
|
14
|
+
[#114]: https://github.com/mvidner/ruby-dbus/pull/114
|
15
|
+
|
5
16
|
## Ruby D-Bus 0.18.0.beta5 - 2022-04-27
|
6
17
|
|
7
18
|
API:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.18.0.
|
1
|
+
0.18.0.beta6
|
data/lib/dbus/data.rb
CHANGED
@@ -35,7 +35,7 @@ module DBus
|
|
35
35
|
# construct an appropriate {Data::Base} instance.
|
36
36
|
#
|
37
37
|
# @param type [SingleCompleteType,Type]
|
38
|
-
# @param value [::Object]
|
38
|
+
# @param value [::Object,Data::Base] a plain value; exact values also allowed
|
39
39
|
# @return [Data::Base]
|
40
40
|
# @raise TypeError
|
41
41
|
def make_typed(type, value)
|
@@ -58,9 +58,13 @@ module DBus
|
|
58
58
|
# @!method self.fixed?
|
59
59
|
# @return [Boolean]
|
60
60
|
|
61
|
-
# @return
|
61
|
+
# @return [::Object] a valid value, plain-Ruby typed.
|
62
|
+
# @see Data::Container#exact_value
|
62
63
|
attr_reader :value
|
63
64
|
|
65
|
+
# @!method self.type_code
|
66
|
+
# @return [String] a single-character string, for example "a" for arrays
|
67
|
+
|
64
68
|
# @!method type
|
65
69
|
# @abstract
|
66
70
|
# Note that for Variants type=="v",
|
@@ -91,11 +95,18 @@ module DBus
|
|
91
95
|
|
92
96
|
# Hash key equality
|
93
97
|
# See https://ruby-doc.org/core-3.0.0/Object.html#method-i-eql-3F
|
94
|
-
|
98
|
+
# Stricter than #== (RSpec: eq), 1==1.0 but 1.eql(1.0)->false
|
99
|
+
def eql?(other)
|
100
|
+
return false unless other.class == self.class
|
101
|
+
|
102
|
+
other.value.eql?(@value)
|
103
|
+
# TODO: this should work, now check derived classes, exact_value
|
104
|
+
end
|
95
105
|
|
96
106
|
# @param type [Type]
|
97
107
|
def self.assert_type_matches_class(type)
|
98
|
-
raise ArgumentError
|
108
|
+
raise ArgumentError, "Expecting #{type_code.inspect} for class #{self}, got #{type.sigtype.inspect}" \
|
109
|
+
unless type.sigtype == type_code
|
99
110
|
end
|
100
111
|
end
|
101
112
|
|
@@ -480,7 +491,7 @@ module DBus
|
|
480
491
|
Byte
|
481
492
|
end
|
482
493
|
|
483
|
-
# @return [Array<Type>]
|
494
|
+
# @return [::Array<Type>]
|
484
495
|
def self.validate_raw!(value)
|
485
496
|
DBus.types(value)
|
486
497
|
rescue Type::SignatureException => e
|
@@ -510,6 +521,29 @@ module DBus
|
|
510
521
|
# For containers, the type varies among instances
|
511
522
|
# @see Base#type
|
512
523
|
attr_reader :type
|
524
|
+
|
525
|
+
# @return something that is, or contains, {Data::Base}.
|
526
|
+
# Er, this docs kinda sucks.
|
527
|
+
def exact_value
|
528
|
+
@value
|
529
|
+
end
|
530
|
+
|
531
|
+
def value
|
532
|
+
@value.map(&:value)
|
533
|
+
end
|
534
|
+
|
535
|
+
# Hash key equality
|
536
|
+
# See https://ruby-doc.org/core-3.0.0/Object.html#method-i-eql-3F
|
537
|
+
# Stricter than #== (RSpec: eq), 1==1.0 but 1.eql(1.0)->false
|
538
|
+
def eql?(other)
|
539
|
+
return false unless other.class == self.class
|
540
|
+
|
541
|
+
other.exact_value.eql?(exact_value)
|
542
|
+
end
|
543
|
+
|
544
|
+
# def ==(other)
|
545
|
+
# eql?(other) || super
|
546
|
+
# end
|
513
547
|
end
|
514
548
|
|
515
549
|
# An Array, or a Dictionary (Hash).
|
@@ -538,16 +572,17 @@ module DBus
|
|
538
572
|
# @param type [Type]
|
539
573
|
# @return [Data::Array]
|
540
574
|
def self.from_typed(value, type:)
|
541
|
-
|
542
|
-
|
543
|
-
member_type = type.child
|
575
|
+
new(value, type: type) # initialize(::Array<Data::Base>)
|
576
|
+
end
|
544
577
|
|
545
|
-
|
546
|
-
|
547
|
-
|
578
|
+
def value
|
579
|
+
v = super
|
580
|
+
if type.child.sigtype == Type::DICT_ENTRY
|
581
|
+
# BTW this makes a copy so mutating it is pointless
|
582
|
+
v.to_h
|
583
|
+
else
|
584
|
+
v
|
548
585
|
end
|
549
|
-
|
550
|
-
new(items, type: type) # initialize(::Array<Data::Base>)
|
551
586
|
end
|
552
587
|
|
553
588
|
# FIXME: should Data::Array be mutable?
|
@@ -556,13 +591,27 @@ module DBus
|
|
556
591
|
# TODO: specify type or guess type?
|
557
592
|
# Data is the exact type, so its constructor should be exact
|
558
593
|
# and guesswork should be clearly labeled
|
594
|
+
|
595
|
+
# @param value [Data::Array,Enumerable]
|
559
596
|
# @param type [SingleCompleteType,Type]
|
560
597
|
def initialize(value, type:)
|
561
|
-
type =
|
598
|
+
type = Type::Factory.make_type(type)
|
562
599
|
self.class.assert_type_matches_class(type)
|
563
600
|
@type = type
|
564
|
-
|
565
|
-
|
601
|
+
|
602
|
+
typed_value = case value
|
603
|
+
when Data::Array
|
604
|
+
raise ArgumentError, "Specified type is #{type} but value type is #{value.type}" \
|
605
|
+
unless value.type == type
|
606
|
+
|
607
|
+
value.exact_value
|
608
|
+
else
|
609
|
+
# TODO: Dict??
|
610
|
+
value.map do |i|
|
611
|
+
Data.make_typed(type.child, i)
|
612
|
+
end
|
613
|
+
end
|
614
|
+
super(typed_value)
|
566
615
|
end
|
567
616
|
end
|
568
617
|
|
@@ -590,25 +639,72 @@ module DBus
|
|
590
639
|
# @param type [Type]
|
591
640
|
# @return [Struct]
|
592
641
|
def self.from_typed(value, type:)
|
593
|
-
|
594
|
-
member_types = type.members
|
595
|
-
raise unless value.size == member_types.size
|
596
|
-
|
597
|
-
items = member_types.zip(value).map do |item_type, item|
|
598
|
-
Data.make_typed(item_type, item)
|
599
|
-
end
|
600
|
-
|
601
|
-
new(items, type: type) # initialize(::Array<Data::Base>)
|
642
|
+
new(value, type: type)
|
602
643
|
end
|
603
644
|
|
645
|
+
# @param value [Data::Struct,Enumerable]
|
646
|
+
# @param type [SingleCompleteType,Type]
|
604
647
|
def initialize(value, type:)
|
648
|
+
type = Type::Factory.make_type(type)
|
605
649
|
self.class.assert_type_matches_class(type)
|
606
650
|
@type = type
|
607
|
-
|
651
|
+
|
652
|
+
typed_value = case value
|
653
|
+
when self.class
|
654
|
+
raise ArgumentError, "Specified type is #{type} but value type is #{value.type}" \
|
655
|
+
unless value.type == type
|
656
|
+
|
657
|
+
value.exact_value
|
658
|
+
else
|
659
|
+
member_types = type.members
|
660
|
+
unless value.size == member_types.size
|
661
|
+
raise ArgumentError, "Specified type has #{member_types.size} members " \
|
662
|
+
"but value has #{value.size} members"
|
663
|
+
end
|
664
|
+
|
665
|
+
member_types.zip(value).map do |item_type, item|
|
666
|
+
Data.make_typed(item_type, item)
|
667
|
+
end
|
668
|
+
end
|
669
|
+
super(typed_value)
|
670
|
+
end
|
671
|
+
|
672
|
+
def ==(other)
|
673
|
+
case other
|
674
|
+
when ::Struct
|
675
|
+
@value.size == other.size &&
|
676
|
+
@value.zip(other.to_a).all? { |i, other_i| i == other_i }
|
677
|
+
else
|
678
|
+
super
|
679
|
+
end
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
# Dictionary/Hash entry.
|
684
|
+
# TODO: shouldn't instantiate?
|
685
|
+
class DictEntry < Struct
|
686
|
+
def self.type_code
|
687
|
+
"e"
|
688
|
+
end
|
689
|
+
|
690
|
+
# @param value [::Array]
|
691
|
+
def self.from_items(value, mode:, type:) # rubocop:disable Lint/UnusedMethodArgument
|
692
|
+
value.freeze
|
693
|
+
# DictEntry ignores the :exact mode
|
694
|
+
value
|
695
|
+
end
|
696
|
+
|
697
|
+
# @param value [::Object] (#size, #each)
|
698
|
+
# @param type [Type]
|
699
|
+
# @return [DictEntry]
|
700
|
+
def self.from_typed(value, type:)
|
701
|
+
new(value, type: type)
|
608
702
|
end
|
609
703
|
end
|
610
704
|
|
611
|
-
# A generic type
|
705
|
+
# A generic type.
|
706
|
+
#
|
707
|
+
# Implementation note: @value is a {Data::Base}.
|
612
708
|
class Variant < Container
|
613
709
|
def self.type_code
|
614
710
|
"v"
|
@@ -618,6 +714,10 @@ module DBus
|
|
618
714
|
1
|
619
715
|
end
|
620
716
|
|
717
|
+
def value
|
718
|
+
@value.value
|
719
|
+
end
|
720
|
+
|
621
721
|
# @param member_type [Type]
|
622
722
|
def self.from_items(value, mode:, member_type:)
|
623
723
|
return value if mode == :plain
|
@@ -631,7 +731,7 @@ module DBus
|
|
631
731
|
def self.from_typed(value, type:)
|
632
732
|
assert_type_matches_class(type)
|
633
733
|
|
634
|
-
# decide on type of value
|
734
|
+
# nil: decide on type of value
|
635
735
|
new(value, member_type: nil)
|
636
736
|
end
|
637
737
|
|
@@ -659,61 +759,24 @@ module DBus
|
|
659
759
|
# @param member_type [Type,nil]
|
660
760
|
def initialize(value, member_type:)
|
661
761
|
# TODO: validate that the given *member_type* matches *value*
|
662
|
-
|
762
|
+
case value
|
763
|
+
when Data::Variant
|
663
764
|
# Copy the contained value instead of boxing it more
|
664
765
|
# TODO: except perhaps for round-tripping in exact mode?
|
665
766
|
@member_type = value.member_type
|
666
|
-
value = value.
|
767
|
+
value = value.exact_value
|
768
|
+
when Data::Base
|
769
|
+
@member_type = member_type || value.type
|
770
|
+
raise ArgumentError, "Variant type #{@member_type} does not match value type #{value.type}" \
|
771
|
+
unless @member_type == value.type
|
667
772
|
else
|
668
773
|
@member_type = member_type || self.class.guess_type(value)
|
774
|
+
value = Data.make_typed(@member_type, value)
|
669
775
|
end
|
670
776
|
super(value)
|
671
777
|
end
|
672
778
|
end
|
673
779
|
|
674
|
-
# Dictionary/Hash entry.
|
675
|
-
# TODO: shouldn't instantiate?
|
676
|
-
class DictEntry < Container
|
677
|
-
def self.type_code
|
678
|
-
"e"
|
679
|
-
end
|
680
|
-
|
681
|
-
def self.alignment
|
682
|
-
8
|
683
|
-
end
|
684
|
-
|
685
|
-
# @param value [::Array]
|
686
|
-
def self.from_items(value, mode:, type:) # rubocop:disable Lint/UnusedMethodArgument
|
687
|
-
value.freeze
|
688
|
-
# DictEntry ignores the :exact mode
|
689
|
-
value
|
690
|
-
end
|
691
|
-
|
692
|
-
# @param value [::Object] (#size, #each)
|
693
|
-
# @param type [Type]
|
694
|
-
# @return [DictEntry]
|
695
|
-
def self.from_typed(value, type:)
|
696
|
-
assert_type_matches_class(type)
|
697
|
-
member_types = type.members
|
698
|
-
# assert member_types.size == 2
|
699
|
-
# TODO: duplicated from Struct. Inherit/delegate?
|
700
|
-
# TODO: validation
|
701
|
-
raise unless value.size == member_types.size
|
702
|
-
|
703
|
-
items = member_types.zip(value).map do |item_type, item|
|
704
|
-
Data.make_typed(item_type, item)
|
705
|
-
end
|
706
|
-
|
707
|
-
new(items, type: type) # initialize(::Array<Data::Base>)
|
708
|
-
end
|
709
|
-
|
710
|
-
def initialize(value, type:)
|
711
|
-
self.class.assert_type_matches_class(type)
|
712
|
-
@type = type
|
713
|
-
super(value)
|
714
|
-
end
|
715
|
-
end
|
716
|
-
|
717
780
|
consts = constants.map { |c_sym| const_get(c_sym) }
|
718
781
|
classes = consts.find_all { |c| c.respond_to?(:type_code) }
|
719
782
|
by_type_code = classes.map { |cl| [cl.type_code, cl] }.to_h
|
data/lib/dbus/marshall.rb
CHANGED
@@ -250,10 +250,10 @@ module DBus
|
|
250
250
|
when Type::VARIANT
|
251
251
|
append_variant(val)
|
252
252
|
when Type::ARRAY
|
253
|
-
val = val.
|
253
|
+
val = val.exact_value if val.is_a?(Data::Array)
|
254
254
|
append_array(type.child, val)
|
255
255
|
when Type::STRUCT, Type::DICT_ENTRY
|
256
|
-
val = val.
|
256
|
+
val = val.exact_value if val.is_a?(Data::Struct) || val.is_a?(Data::DictEntry)
|
257
257
|
unless val.is_a?(Array) || val.is_a?(Struct)
|
258
258
|
type_name = Type::TYPE_MAPPING[type.sigtype].first
|
259
259
|
raise TypeException, "#{type_name} expects an Array or Struct, seen #{val.class}"
|
@@ -284,7 +284,10 @@ module DBus
|
|
284
284
|
vartype = nil
|
285
285
|
if val.is_a?(DBus::Data::Variant)
|
286
286
|
vartype = val.member_type
|
287
|
-
vardata = val.
|
287
|
+
vardata = val.exact_value
|
288
|
+
elsif val.is_a?(DBus::Data::Container)
|
289
|
+
vartype = val.type
|
290
|
+
vardata = val.exact_value
|
288
291
|
elsif val.is_a?(DBus::Data::Base)
|
289
292
|
vartype = val.type
|
290
293
|
vardata = val.value
|
data/lib/dbus/type.rb
CHANGED
@@ -107,6 +107,29 @@ module DBus
|
|
107
107
|
freeze
|
108
108
|
end
|
109
109
|
|
110
|
+
# A Type is equal to
|
111
|
+
# - another Type with the same string representation
|
112
|
+
# - a String ({SingleCompleteType}) describing the type
|
113
|
+
def ==(other)
|
114
|
+
case other
|
115
|
+
when ::String
|
116
|
+
to_s == other
|
117
|
+
else
|
118
|
+
eql?(other)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# A Type is eql? to
|
123
|
+
# - another Type with the same string representation
|
124
|
+
#
|
125
|
+
# Hash key equality
|
126
|
+
# See https://ruby-doc.org/core-3.0.0/Object.html#method-i-eql-3F
|
127
|
+
def eql?(other)
|
128
|
+
return false unless other.is_a?(Type)
|
129
|
+
|
130
|
+
@sigtype == other.sigtype && @members == other.members
|
131
|
+
end
|
132
|
+
|
110
133
|
# Return the required alignment for the type.
|
111
134
|
def alignment
|
112
135
|
TYPE_MAPPING[@sigtype].last
|
@@ -157,7 +180,7 @@ module DBus
|
|
157
180
|
|
158
181
|
def inspect
|
159
182
|
s = TYPE_MAPPING[@sigtype].first
|
160
|
-
if [STRUCT, ARRAY].member?(@sigtype)
|
183
|
+
if [STRUCT, ARRAY, DICT_ENTRY].member?(@sigtype)
|
161
184
|
s += ": #{@members.inspect}"
|
162
185
|
end
|
163
186
|
s
|
data/spec/data_spec.rb
CHANGED
@@ -6,14 +6,140 @@ require "dbus"
|
|
6
6
|
|
7
7
|
# The from_raw methods are tested in packet_unmarshaller_spec.rb
|
8
8
|
|
9
|
+
RSpec.shared_examples "#== and #eql? work for basic types" do |*args|
|
10
|
+
plain_a = args.fetch(0, 22)
|
11
|
+
plain_b = args.fetch(1, 222)
|
12
|
+
|
13
|
+
context "with #{plain_a.inspect} and #{plain_b.inspect}" do
|
14
|
+
describe "#eql?" do
|
15
|
+
it "returns true for same class and value" do
|
16
|
+
a = described_class.new(plain_a)
|
17
|
+
b = described_class.new(plain_a)
|
18
|
+
expect(a).to eql(b)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns false for same class, different value" do
|
22
|
+
a = described_class.new(plain_a)
|
23
|
+
b = described_class.new(plain_b)
|
24
|
+
expect(a).to_not eql(b)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns false for same value but plain class" do
|
28
|
+
a = described_class.new(plain_a)
|
29
|
+
b = plain_a
|
30
|
+
expect(a).to_not eql(b)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#==" do
|
35
|
+
it "returns true for same class and value" do
|
36
|
+
a = described_class.new(plain_a)
|
37
|
+
b = described_class.new(plain_a)
|
38
|
+
expect(a).to eq(b)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns false for same class, different value" do
|
42
|
+
a = described_class.new(plain_a)
|
43
|
+
b = described_class.new(plain_b)
|
44
|
+
expect(a).to_not eq(b)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns true for same value but plain class" do
|
48
|
+
a = described_class.new(plain_a)
|
49
|
+
b = plain_a
|
50
|
+
expect(a).to eq(b)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
RSpec.shared_examples "#== and #eql? work for container types (1 value)" do |plain_a, a_kwargs|
|
57
|
+
a1 = described_class.new(plain_a, **a_kwargs)
|
58
|
+
a2 = described_class.new(plain_a, **a_kwargs)
|
59
|
+
|
60
|
+
context "with #{plain_a.inspect}, #{a_kwargs.inspect}" do
|
61
|
+
describe "#eql?" do
|
62
|
+
it "returns true for same class and value" do
|
63
|
+
expect(a1).to eql(a2)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns false for same value but plain class" do
|
67
|
+
expect(a1).to_not eql(plain_a)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#==" do
|
72
|
+
it "returns true for same class and value" do
|
73
|
+
expect(a1).to eq(a2)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns true for same value but plain class" do
|
77
|
+
expect(a1).to eq(plain_a)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
RSpec.shared_examples "#== and #eql? work for container types (inequal)" do |plain_a, a_kwargs, plain_b, b_kwargs|
|
84
|
+
# RSpec note: if the shared_examples is used via include_examples more than
|
85
|
+
# once in a single context, `let` would take value from just one of them.
|
86
|
+
# So use plain assignment.
|
87
|
+
a = described_class.new(plain_a, **a_kwargs)
|
88
|
+
b = described_class.new(plain_b, **b_kwargs)
|
89
|
+
|
90
|
+
include_examples "#== and #eql? work for container types (1 value)", plain_a, a_kwargs
|
91
|
+
|
92
|
+
context "with #{plain_a.inspect}, #{a_kwargs.inspect} and #{plain_b.inspect}, #{b_kwargs.inspect}" do
|
93
|
+
describe "#eql?" do
|
94
|
+
it "returns false for same class, different value" do
|
95
|
+
expect(a).to_not eql(b)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#==" do
|
100
|
+
it "returns false for same class, different value" do
|
101
|
+
expect(a).to_not eq(b)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
RSpec.shared_examples "#== and #eql? work for container types (equal)" do |plain_a, a_kwargs, plain_b, b_kwargs|
|
108
|
+
a = described_class.new(plain_a, **a_kwargs)
|
109
|
+
b = described_class.new(plain_b, **b_kwargs)
|
110
|
+
|
111
|
+
include_examples "#== and #eql? work for container types (1 value)", plain_a, a_kwargs
|
112
|
+
|
113
|
+
context "with #{plain_a.inspect}, #{a_kwargs.inspect} and #{plain_b.inspect}, #{b_kwargs.inspect}" do
|
114
|
+
describe "#eql?" do
|
115
|
+
it "returns true for same class, differently expressed value" do
|
116
|
+
expect(a).to eql(b)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#==" do
|
121
|
+
it "returns true for same class, differently expressed value" do
|
122
|
+
expect(a).to eq(b)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#==" do
|
127
|
+
it "returns true for plain, differently expressed value" do
|
128
|
+
expect(a).to eq(plain_b)
|
129
|
+
expect(b).to eq(plain_a)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
9
135
|
RSpec.shared_examples "constructor accepts numeric range" do |min, max|
|
10
136
|
describe "#initialize" do
|
11
137
|
it "accepts the min value #{min}" do
|
12
|
-
expect(described_class.new(min).value).to
|
138
|
+
expect(described_class.new(min).value).to eql(min)
|
13
139
|
end
|
14
140
|
|
15
141
|
it "accepts the max value #{max}" do
|
16
|
-
expect(described_class.new(max).value).to
|
142
|
+
expect(described_class.new(max).value).to eql(max)
|
17
143
|
end
|
18
144
|
|
19
145
|
it "raises on too small a value #{min - 1}" do
|
@@ -34,27 +160,30 @@ RSpec.shared_examples "constructor accepts plain or typed values" do |plain_list
|
|
34
160
|
describe "#initialize" do
|
35
161
|
Array(plain_list).each do |plain|
|
36
162
|
it "accepts the plain value #{plain.inspect}" do
|
37
|
-
expect(described_class.new(plain).value).to
|
163
|
+
expect(described_class.new(plain).value).to eql(plain)
|
164
|
+
expect(described_class.new(plain)).to eq(plain)
|
38
165
|
end
|
39
166
|
|
40
167
|
it "accepts the typed value #{plain.inspect}" do
|
41
168
|
typed = described_class.new(plain)
|
42
|
-
expect(described_class.new(typed).value).to
|
169
|
+
expect(described_class.new(typed).value).to eql(plain)
|
170
|
+
expect(described_class.new(typed)).to eq(plain)
|
43
171
|
end
|
44
172
|
end
|
45
173
|
end
|
46
174
|
end
|
47
175
|
|
176
|
+
# FIXME: decide eq and eql here
|
48
177
|
RSpec.shared_examples "constructor (kwargs) accepts values" do |list|
|
49
178
|
describe "#initialize" do
|
50
179
|
list.each do |value, kwargs_hash|
|
51
180
|
it "accepts the plain value #{value.inspect}, #{kwargs_hash.inspect}" do
|
52
|
-
expect(described_class.new(value, **kwargs_hash)
|
181
|
+
expect(described_class.new(value, **kwargs_hash)).to eq(value)
|
53
182
|
end
|
54
183
|
|
55
184
|
it "accepts the typed value #{value.inspect}, #{kwargs_hash.inspect}" do
|
56
185
|
typed = described_class.new(value, **kwargs_hash)
|
57
|
-
expect(described_class.new(typed, **kwargs_hash)
|
186
|
+
expect(described_class.new(typed, **kwargs_hash)).to eq(value)
|
58
187
|
end
|
59
188
|
end
|
60
189
|
end
|
@@ -93,36 +222,43 @@ describe DBus::Data do
|
|
93
222
|
# Kick InvalidPacketException out of here?
|
94
223
|
|
95
224
|
describe DBus::Data::Byte do
|
225
|
+
include_examples "#== and #eql? work for basic types"
|
96
226
|
include_examples "constructor accepts numeric range", 0, 2**8 - 1
|
97
227
|
include_examples "constructor accepts plain or typed values", 42
|
98
228
|
end
|
99
229
|
|
100
230
|
describe DBus::Data::Int16 do
|
231
|
+
include_examples "#== and #eql? work for basic types"
|
101
232
|
include_examples "constructor accepts numeric range", -2**15, 2**15 - 1
|
102
233
|
include_examples "constructor accepts plain or typed values", 42
|
103
234
|
end
|
104
235
|
|
105
236
|
describe DBus::Data::UInt16 do
|
237
|
+
include_examples "#== and #eql? work for basic types"
|
106
238
|
include_examples "constructor accepts numeric range", 0, 2**16 - 1
|
107
239
|
include_examples "constructor accepts plain or typed values", 42
|
108
240
|
end
|
109
241
|
|
110
242
|
describe DBus::Data::Int32 do
|
243
|
+
include_examples "#== and #eql? work for basic types"
|
111
244
|
include_examples "constructor accepts numeric range", -2**31, 2**31 - 1
|
112
245
|
include_examples "constructor accepts plain or typed values", 42
|
113
246
|
end
|
114
247
|
|
115
248
|
describe DBus::Data::UInt32 do
|
249
|
+
include_examples "#== and #eql? work for basic types"
|
116
250
|
include_examples "constructor accepts numeric range", 0, 2**32 - 1
|
117
251
|
include_examples "constructor accepts plain or typed values", 42
|
118
252
|
end
|
119
253
|
|
120
254
|
describe DBus::Data::Int64 do
|
255
|
+
include_examples "#== and #eql? work for basic types"
|
121
256
|
include_examples "constructor accepts numeric range", -2**63, 2**63 - 1
|
122
257
|
include_examples "constructor accepts plain or typed values", 42
|
123
258
|
end
|
124
259
|
|
125
260
|
describe DBus::Data::UInt64 do
|
261
|
+
include_examples "#== and #eql? work for basic types"
|
126
262
|
include_examples "constructor accepts numeric range", 0, 2**64 - 1
|
127
263
|
include_examples "constructor accepts plain or typed values", 42
|
128
264
|
end
|
@@ -142,10 +278,12 @@ describe DBus::Data do
|
|
142
278
|
end
|
143
279
|
end
|
144
280
|
|
281
|
+
include_examples "#== and #eql? work for basic types", false, true
|
145
282
|
include_examples "constructor accepts plain or typed values", false
|
146
283
|
end
|
147
284
|
|
148
285
|
describe DBus::Data::Double do
|
286
|
+
include_examples "#== and #eql? work for basic types"
|
149
287
|
include_examples "constructor accepts plain or typed values", Math::PI
|
150
288
|
|
151
289
|
describe "#initialize" do
|
@@ -183,6 +321,7 @@ describe DBus::Data do
|
|
183
321
|
["\xF4\x90\xC0\xC0", DBus::InvalidPacketException, "not in UTF-8"]
|
184
322
|
]
|
185
323
|
|
324
|
+
include_examples "#== and #eql? work for basic types", "foo", "bar"
|
186
325
|
include_examples "constructor accepts plain or typed values", good
|
187
326
|
include_examples "constructor rejects values from this list", bad
|
188
327
|
|
@@ -206,6 +345,7 @@ describe DBus::Data do
|
|
206
345
|
# TODO: others
|
207
346
|
]
|
208
347
|
|
348
|
+
include_examples "#== and #eql? work for basic types", "/foo", "/bar"
|
209
349
|
include_examples "constructor accepts plain or typed values", good
|
210
350
|
include_examples "constructor rejects values from this list", bad
|
211
351
|
|
@@ -231,6 +371,7 @@ describe DBus::Data do
|
|
231
371
|
# TODO: others
|
232
372
|
]
|
233
373
|
|
374
|
+
include_examples "#== and #eql? work for basic types", "aah", "aaaaah"
|
234
375
|
include_examples "constructor accepts plain or typed values", good
|
235
376
|
include_examples "constructor rejects values from this list", bad
|
236
377
|
|
@@ -262,6 +403,14 @@ describe DBus::Data do
|
|
262
403
|
# TODO: others
|
263
404
|
]
|
264
405
|
|
406
|
+
include_examples "#== and #eql? work for container types (inequal)",
|
407
|
+
[1, 2, 3], { type: "aq" },
|
408
|
+
[3, 2, 1], { type: "aq" }
|
409
|
+
|
410
|
+
include_examples "#== and #eql? work for container types (inequal)",
|
411
|
+
[[1, 2, 3]], { type: "aaq" },
|
412
|
+
[[3, 2, 1]], { type: "aaq" }
|
413
|
+
|
265
414
|
include_examples "constructor (kwargs) accepts values", good
|
266
415
|
include_examples "constructor (kwargs) rejects values", bad
|
267
416
|
|
@@ -315,6 +464,14 @@ describe DBus::Data do
|
|
315
464
|
# TODO: others
|
316
465
|
]
|
317
466
|
|
467
|
+
include_examples "#== and #eql? work for container types (inequal)",
|
468
|
+
[1, 2, 3], { type: qqq },
|
469
|
+
[3, 2, 1], { type: qqq }
|
470
|
+
|
471
|
+
include_examples "#== and #eql? work for container types (equal)",
|
472
|
+
three_words.new(*integers), { type: qqq },
|
473
|
+
[1, 2, 3], { type: qqq }
|
474
|
+
|
318
475
|
include_examples "constructor (kwargs) accepts values", good
|
319
476
|
# include_examples "constructor (kwargs) rejects values", bad
|
320
477
|
|
@@ -325,6 +482,108 @@ describe DBus::Data do
|
|
325
482
|
.to be_a(described_class)
|
326
483
|
end
|
327
484
|
end
|
485
|
+
|
486
|
+
describe "#initialize" do
|
487
|
+
it "converts type to Type" do
|
488
|
+
value = [1, 2, 3]
|
489
|
+
type = "(uuu)"
|
490
|
+
result = described_class.new(value, type: type)
|
491
|
+
expect(result.type).to be_a DBus::Type
|
492
|
+
end
|
493
|
+
|
494
|
+
it "checks that type matches class" do
|
495
|
+
value = [1, 2, 3]
|
496
|
+
type = T::Array[T::INT32]
|
497
|
+
expect { described_class.new(value, type: type) }
|
498
|
+
.to raise_error(ArgumentError, /Expecting "r"/)
|
499
|
+
end
|
500
|
+
|
501
|
+
it "checks type of a Data::Struct value" do
|
502
|
+
value1 = [1, 2, 3]
|
503
|
+
type1 = "(uuu)"
|
504
|
+
result1 = described_class.new(value1, type: type1)
|
505
|
+
|
506
|
+
value2 = result1
|
507
|
+
type2 = "(xxx)"
|
508
|
+
expect { described_class.new(value2, type: type2) }
|
509
|
+
.to raise_error(ArgumentError, /value type is .uuu./)
|
510
|
+
end
|
511
|
+
|
512
|
+
it "checks that size of type and value match" do
|
513
|
+
value = [1, 2, 3, 4]
|
514
|
+
type = "(uuu)"
|
515
|
+
expect { described_class.new(value, type: type) }
|
516
|
+
.to raise_error(ArgumentError, /type has 3 members.*value has 4 members/)
|
517
|
+
end
|
518
|
+
|
519
|
+
it "converts value to ::Array of Data::Base" do
|
520
|
+
value = three_words.new(*integers)
|
521
|
+
type = T::Struct[T::INT32, T::INT32, T::INT32]
|
522
|
+
result = described_class.new(value, type: type)
|
523
|
+
|
524
|
+
expect(result.exact_value).to be_an(::Array)
|
525
|
+
expect(result.exact_value[0]).to be_a(DBus::Data::Base)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
describe DBus::Data::DictEntry do
|
531
|
+
describe ".from_typed" do
|
532
|
+
it "creates new instance from given object and type" do
|
533
|
+
type = T::Hash[String, T::INT16].child
|
534
|
+
expect(described_class.from_typed(["test", 12], type: type))
|
535
|
+
.to be_a(described_class)
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
describe "#initialize" do
|
540
|
+
it "checks that type matches class" do
|
541
|
+
value = [1, 2]
|
542
|
+
type = T::Array[T::INT32]
|
543
|
+
|
544
|
+
expect { described_class.new(value, type: type) }
|
545
|
+
.to raise_error(ArgumentError, /Expecting "e"/)
|
546
|
+
end
|
547
|
+
|
548
|
+
it "checks type of a Data::DictEntry value" do
|
549
|
+
value1 = [1, 2]
|
550
|
+
type1 = T::Hash[T::UINT32, T::UINT32].child
|
551
|
+
result1 = described_class.new(value1, type: type1)
|
552
|
+
|
553
|
+
value2 = result1
|
554
|
+
type2 = T::Hash[T::UINT64, T::UINT64].child
|
555
|
+
expect { described_class.new(value2, type: type2) }
|
556
|
+
.to raise_error(ArgumentError, /value type is .uu./)
|
557
|
+
end
|
558
|
+
|
559
|
+
it "checks that size of type and value match" do
|
560
|
+
value = [1, 2, 3]
|
561
|
+
type = T::Hash[T::UINT32, T::UINT32].child
|
562
|
+
expect { described_class.new(value, type: type) }
|
563
|
+
.to raise_error(ArgumentError, /type has 2 members.*value has 3 members/)
|
564
|
+
end
|
565
|
+
|
566
|
+
it "converts value to ::Array of Data::Base" do
|
567
|
+
two_words = ::Struct.new(:k, :v)
|
568
|
+
value = two_words.new(1, 2)
|
569
|
+
type = T::Hash[T::UINT32, T::UINT32].child
|
570
|
+
result = described_class.new(value, type: type)
|
571
|
+
|
572
|
+
expect(result.exact_value).to be_an(::Array)
|
573
|
+
expect(result.exact_value[0]).to be_a(DBus::Data::Base)
|
574
|
+
end
|
575
|
+
|
576
|
+
it "takes a plain value" do
|
577
|
+
input = ["test", 23]
|
578
|
+
|
579
|
+
type = T::Hash[String, T::INT16].child
|
580
|
+
value = described_class.new(input, type: type)
|
581
|
+
|
582
|
+
expect(value).to be_a(described_class)
|
583
|
+
expect(value.type.to_s).to eq "{sn}"
|
584
|
+
expect(value.value).to eql input
|
585
|
+
end
|
586
|
+
end
|
328
587
|
end
|
329
588
|
|
330
589
|
describe DBus::Data::Variant do
|
@@ -337,9 +596,42 @@ describe DBus::Data do
|
|
337
596
|
expect(value.member_type.to_s).to eq "s"
|
338
597
|
end
|
339
598
|
end
|
340
|
-
end
|
341
599
|
|
342
|
-
|
600
|
+
describe "#initialize" do
|
601
|
+
it "takes a plain value" do
|
602
|
+
input = 42
|
603
|
+
|
604
|
+
type = DBus.type(T::INT16)
|
605
|
+
value = described_class.new(input, member_type: type)
|
606
|
+
expect(value).to be_a(described_class)
|
607
|
+
expect(value.type.to_s).to eq "v"
|
608
|
+
expect(value.member_type.to_s).to eq "n"
|
609
|
+
expect(value.value).to eq 42
|
610
|
+
end
|
611
|
+
|
612
|
+
# FIXME: verify that @value has the correct class
|
613
|
+
it "takes an exact value" do
|
614
|
+
input = DBus::Data::Int16.new(42)
|
615
|
+
|
616
|
+
type = DBus.type(T::INT16)
|
617
|
+
value = described_class.new(input, member_type: type)
|
618
|
+
expect(value).to be_a(described_class)
|
619
|
+
expect(value.type.to_s).to eq "v"
|
620
|
+
expect(value.member_type.to_s).to eq "n"
|
621
|
+
expect(value.value).to eq 42
|
622
|
+
end
|
623
|
+
|
624
|
+
it "checks the type of the exact value" do
|
625
|
+
input = DBus::Data::UInt16.new(42)
|
626
|
+
|
627
|
+
type = DBus.type(T::INT16)
|
628
|
+
expect { described_class.new(input, member_type: type) }
|
629
|
+
.to raise_error(ArgumentError, /Variant type n does not match value type q/)
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
include_examples "#== and #eql? work for container types (1 value)",
|
634
|
+
"/foo", { member_type: DBus.type(T::STRING) }
|
343
635
|
end
|
344
636
|
end
|
345
637
|
end
|
@@ -48,14 +48,7 @@ RSpec.shared_examples "parses good data" do |cases|
|
|
48
48
|
result = results.first
|
49
49
|
|
50
50
|
expect(result).to be_a(DBus::Data::Base)
|
51
|
-
|
52
|
-
expect(result.value.size).to eq(expected.size)
|
53
|
-
result.value.each_key do |result_key|
|
54
|
-
expect(result.value[result_key]).to eq(expected[result_key.value])
|
55
|
-
end
|
56
|
-
else
|
57
|
-
expect(result.value).to eq(expected)
|
58
|
-
end
|
51
|
+
expect(result.value).to eq(expected)
|
59
52
|
|
60
53
|
expect(remaining_buffer(subject)).to be_empty
|
61
54
|
end
|
@@ -106,14 +99,7 @@ describe DBus::PacketUnmarshaller do
|
|
106
99
|
result = results.first
|
107
100
|
|
108
101
|
expect(result).to be_a(DBus::Data::Base)
|
109
|
-
|
110
|
-
expect(result.value.size).to eq(expected.size)
|
111
|
-
result.value.each_key do |result_key|
|
112
|
-
expect(result.value[result_key]).to eq(expected[result_key.value])
|
113
|
-
end
|
114
|
-
else
|
115
|
-
expect(result.value).to eq(expected)
|
116
|
-
end
|
102
|
+
expect(result.value).to eq(expected)
|
117
103
|
|
118
104
|
expect(remaining_buffer(subject)).to be_empty
|
119
105
|
end
|
data/spec/type_spec.rb
CHANGED
@@ -82,6 +82,46 @@ describe DBus do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
describe DBus::Type do
|
85
|
+
let(:as1) { DBus.type("as") }
|
86
|
+
let(:as2) { DBus.type("as") }
|
87
|
+
let(:aas) { DBus.type("aas") }
|
88
|
+
|
89
|
+
describe "#==" do
|
90
|
+
it "is true for same types" do
|
91
|
+
expect(as1).to eq(as2)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "is true for a type and its string representation" do
|
95
|
+
expect(as1).to eq("as")
|
96
|
+
end
|
97
|
+
|
98
|
+
it "is false for different types" do
|
99
|
+
expect(as1).to_not eq(aas)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "is false for a type and a different string" do
|
103
|
+
expect(as1).to_not eq("aas")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#eql?" do
|
108
|
+
it "is true for same types" do
|
109
|
+
expect(as1).to eql(as2)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "is false for a type and its string representation" do
|
113
|
+
expect(as1).to_not eql("as")
|
114
|
+
end
|
115
|
+
|
116
|
+
it "is false for different types" do
|
117
|
+
expect(as1).to_not eql(aas)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "is false for a type and a different string" do
|
121
|
+
expect(as1).to_not eql("aas")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
85
125
|
describe "#<<" do
|
86
126
|
it "raises if the argument is not a Type" do
|
87
127
|
t = DBus::Type.new(DBus::Type::ARRAY)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-dbus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.18.0.
|
4
|
+
version: 0.18.0.beta6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruby DBus Team
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rexml
|
@@ -202,7 +202,7 @@ homepage: https://github.com/mvidner/ruby-dbus
|
|
202
202
|
licenses:
|
203
203
|
- LGPL-2.1
|
204
204
|
metadata: {}
|
205
|
-
post_install_message:
|
205
|
+
post_install_message:
|
206
206
|
rdoc_options: []
|
207
207
|
require_paths:
|
208
208
|
- lib
|
@@ -217,9 +217,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
217
|
- !ruby/object:Gem::Version
|
218
218
|
version: 1.3.1
|
219
219
|
requirements: []
|
220
|
-
|
221
|
-
|
222
|
-
signing_key:
|
220
|
+
rubygems_version: 3.3.0.dev
|
221
|
+
signing_key:
|
223
222
|
specification_version: 4
|
224
223
|
summary: Ruby module for interaction with D-Bus
|
225
224
|
test_files: []
|