ruby-dbus 0.18.0.beta3 → 0.18.0.beta6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/NEWS.md +38 -0
- data/VERSION +1 -1
- data/lib/dbus/data.rb +201 -158
- data/lib/dbus/marshall.rb +23 -8
- data/lib/dbus/type.rb +144 -15
- data/spec/data/marshall.yaml +28 -0
- data/spec/data_spec.rb +328 -44
- data/spec/packet_marshaller_spec.rb +7 -0
- data/spec/packet_unmarshaller_spec.rb +2 -16
- data/spec/property_spec.rb +48 -2
- data/spec/service_newapi.rb +4 -4
- data/spec/type_spec.rb +145 -0
- metadata +6 -7
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
|
@@ -85,42 +214,51 @@ end
|
|
85
214
|
# TODO: Look at conversions? to_str, to_int?
|
86
215
|
|
87
216
|
describe DBus::Data do
|
217
|
+
T = DBus::Type unless const_defined? "T"
|
218
|
+
|
88
219
|
# test initialization, from user code, or from packet (from_raw)
|
89
220
|
# remember to unpack if initializing from Data::Base
|
90
221
|
# #value should recurse inside so that the user doesnt have to
|
91
222
|
# Kick InvalidPacketException out of here?
|
92
223
|
|
93
224
|
describe DBus::Data::Byte do
|
225
|
+
include_examples "#== and #eql? work for basic types"
|
94
226
|
include_examples "constructor accepts numeric range", 0, 2**8 - 1
|
95
227
|
include_examples "constructor accepts plain or typed values", 42
|
96
228
|
end
|
97
229
|
|
98
230
|
describe DBus::Data::Int16 do
|
231
|
+
include_examples "#== and #eql? work for basic types"
|
99
232
|
include_examples "constructor accepts numeric range", -2**15, 2**15 - 1
|
100
233
|
include_examples "constructor accepts plain or typed values", 42
|
101
234
|
end
|
102
235
|
|
103
236
|
describe DBus::Data::UInt16 do
|
237
|
+
include_examples "#== and #eql? work for basic types"
|
104
238
|
include_examples "constructor accepts numeric range", 0, 2**16 - 1
|
105
239
|
include_examples "constructor accepts plain or typed values", 42
|
106
240
|
end
|
107
241
|
|
108
242
|
describe DBus::Data::Int32 do
|
243
|
+
include_examples "#== and #eql? work for basic types"
|
109
244
|
include_examples "constructor accepts numeric range", -2**31, 2**31 - 1
|
110
245
|
include_examples "constructor accepts plain or typed values", 42
|
111
246
|
end
|
112
247
|
|
113
248
|
describe DBus::Data::UInt32 do
|
249
|
+
include_examples "#== and #eql? work for basic types"
|
114
250
|
include_examples "constructor accepts numeric range", 0, 2**32 - 1
|
115
251
|
include_examples "constructor accepts plain or typed values", 42
|
116
252
|
end
|
117
253
|
|
118
254
|
describe DBus::Data::Int64 do
|
255
|
+
include_examples "#== and #eql? work for basic types"
|
119
256
|
include_examples "constructor accepts numeric range", -2**63, 2**63 - 1
|
120
257
|
include_examples "constructor accepts plain or typed values", 42
|
121
258
|
end
|
122
259
|
|
123
260
|
describe DBus::Data::UInt64 do
|
261
|
+
include_examples "#== and #eql? work for basic types"
|
124
262
|
include_examples "constructor accepts numeric range", 0, 2**64 - 1
|
125
263
|
include_examples "constructor accepts plain or typed values", 42
|
126
264
|
end
|
@@ -140,10 +278,12 @@ describe DBus::Data do
|
|
140
278
|
end
|
141
279
|
end
|
142
280
|
|
281
|
+
include_examples "#== and #eql? work for basic types", false, true
|
143
282
|
include_examples "constructor accepts plain or typed values", false
|
144
283
|
end
|
145
284
|
|
146
285
|
describe DBus::Data::Double do
|
286
|
+
include_examples "#== and #eql? work for basic types"
|
147
287
|
include_examples "constructor accepts plain or typed values", Math::PI
|
148
288
|
|
149
289
|
describe "#initialize" do
|
@@ -181,6 +321,7 @@ describe DBus::Data do
|
|
181
321
|
["\xF4\x90\xC0\xC0", DBus::InvalidPacketException, "not in UTF-8"]
|
182
322
|
]
|
183
323
|
|
324
|
+
include_examples "#== and #eql? work for basic types", "foo", "bar"
|
184
325
|
include_examples "constructor accepts plain or typed values", good
|
185
326
|
include_examples "constructor rejects values from this list", bad
|
186
327
|
|
@@ -204,6 +345,7 @@ describe DBus::Data do
|
|
204
345
|
# TODO: others
|
205
346
|
]
|
206
347
|
|
348
|
+
include_examples "#== and #eql? work for basic types", "/foo", "/bar"
|
207
349
|
include_examples "constructor accepts plain or typed values", good
|
208
350
|
include_examples "constructor rejects values from this list", bad
|
209
351
|
|
@@ -229,6 +371,7 @@ describe DBus::Data do
|
|
229
371
|
# TODO: others
|
230
372
|
]
|
231
373
|
|
374
|
+
include_examples "#== and #eql? work for basic types", "aah", "aaaaah"
|
232
375
|
include_examples "constructor accepts plain or typed values", good
|
233
376
|
include_examples "constructor rejects values from this list", bad
|
234
377
|
|
@@ -245,28 +388,36 @@ describe DBus::Data do
|
|
245
388
|
describe "containers" do
|
246
389
|
describe DBus::Data::Array do
|
247
390
|
good = [
|
248
|
-
# [[1, 2, 3],
|
249
|
-
[[1, 2, 3], {
|
250
|
-
[[1, 2, 3], {
|
251
|
-
[[1, 2, 3], {
|
252
|
-
[[DBus::Data::UInt16.new(1), DBus::Data::UInt16.new(2), DBus::Data::UInt16.new(3)], {
|
391
|
+
# [[1, 2, 3], type: nil],
|
392
|
+
[[1, 2, 3], { type: "aq" }],
|
393
|
+
[[1, 2, 3], { type: T::Array[T::UINT16] }],
|
394
|
+
[[1, 2, 3], { type: T::Array["q"] }],
|
395
|
+
[[DBus::Data::UInt16.new(1), DBus::Data::UInt16.new(2), DBus::Data::UInt16.new(3)], { type: T::Array["q"] }]
|
253
396
|
# TODO: others
|
254
397
|
]
|
255
398
|
|
256
399
|
bad = [
|
257
400
|
# undesirable type guessing
|
258
|
-
## [[1, 2, 3], {
|
259
|
-
## [[1, 2, 3], {
|
401
|
+
## [[1, 2, 3], { type: nil }, DBus::InvalidPacketException, "Unknown type code"],
|
402
|
+
## [[1, 2, 3], { type: "!" }, DBus::InvalidPacketException, "Unknown type code"]
|
260
403
|
# TODO: others
|
261
404
|
]
|
262
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
|
+
|
263
414
|
include_examples "constructor (kwargs) accepts values", good
|
264
415
|
include_examples "constructor (kwargs) rejects values", bad
|
265
416
|
|
266
417
|
describe ".from_typed" do
|
267
418
|
it "creates new instance from given object and type" do
|
268
|
-
type =
|
269
|
-
expect(described_class.from_typed(["test", "lest"],
|
419
|
+
type = T::Array[String]
|
420
|
+
expect(described_class.from_typed(["test", "lest"], type: type)).to be_a(described_class)
|
270
421
|
end
|
271
422
|
end
|
272
423
|
end
|
@@ -274,7 +425,7 @@ describe DBus::Data do
|
|
274
425
|
describe DBus::Data::Struct do
|
275
426
|
three_words = ::Struct.new(:a, :b, :c)
|
276
427
|
|
277
|
-
qqq = [
|
428
|
+
qqq = T::Struct[T::UINT16, T::UINT16, T::UINT16]
|
278
429
|
integers = [1, 2, 3]
|
279
430
|
uints = [DBus::Data::UInt16.new(1), DBus::Data::UInt16.new(2), DBus::Data::UInt16.new(3)]
|
280
431
|
|
@@ -291,63 +442,196 @@ describe DBus::Data do
|
|
291
442
|
# TODO: also check data ownership: reasonable to own the data?
|
292
443
|
# can make it explicit?
|
293
444
|
good = [
|
294
|
-
# from plain array; various
|
295
|
-
[integers, {
|
296
|
-
[integers, {
|
297
|
-
[integers, {
|
445
|
+
# from plain array; various *type* styles
|
446
|
+
[integers, { type: DBus.type("(qqq)") }],
|
447
|
+
[integers, { type: T::Struct["q", "q", "q"] }],
|
448
|
+
[integers, { type: T::Struct[T::UINT16, T::UINT16, T::UINT16] }],
|
449
|
+
[integers, { type: T::Struct[*DBus.types("qqq")] }],
|
298
450
|
# plain array of data
|
299
|
-
[uints, {
|
451
|
+
[uints, { type: qqq }],
|
300
452
|
# ::Struct
|
301
|
-
[three_words.new(*integers), {
|
302
|
-
[three_words.new(*uints), {
|
453
|
+
[three_words.new(*integers), { type: qqq }],
|
454
|
+
[three_words.new(*uints), { type: qqq }]
|
303
455
|
# TODO: others
|
304
456
|
]
|
305
457
|
|
458
|
+
# check these only when canonicalizing @value, because that will
|
459
|
+
# type-check the value deeply
|
306
460
|
_bad_but_valid = [
|
307
|
-
# Wrong member_types arg:
|
308
|
-
# hmm this is another reason to pass the type
|
309
|
-
# as the entire struct type, not the members:
|
310
|
-
# empty struct will be caught naturally
|
311
|
-
[integers, { member_types: [] }, ArgumentError, "???"],
|
312
|
-
[integers, { member_types: ["!"] }, DBus::InvalidPacketException, "Unknown type code"],
|
313
461
|
# STRUCT specific: member count mismatch
|
314
|
-
[[1, 2], {
|
315
|
-
[[1, 2, 3, 4], {
|
462
|
+
[[1, 2], { type: qqq }, ArgumentError, "???"],
|
463
|
+
[[1, 2, 3, 4], { type: qqq }, ArgumentError, "???"]
|
316
464
|
# TODO: others
|
317
465
|
]
|
318
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
|
+
|
319
475
|
include_examples "constructor (kwargs) accepts values", good
|
320
476
|
# include_examples "constructor (kwargs) rejects values", bad
|
321
477
|
|
322
478
|
describe ".from_typed" do
|
323
479
|
it "creates new instance from given object and type" do
|
324
|
-
type =
|
325
|
-
expect(described_class.from_typed(["test", "lest"].freeze,
|
480
|
+
type = T::Struct[T::STRING, T::STRING]
|
481
|
+
expect(described_class.from_typed(["test", "lest"].freeze, type: type))
|
326
482
|
.to be_a(described_class)
|
327
483
|
end
|
328
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
|
329
528
|
end
|
330
529
|
|
331
|
-
describe DBus::Data::
|
530
|
+
describe DBus::Data::DictEntry do
|
332
531
|
describe ".from_typed" do
|
333
532
|
it "creates new instance from given object and type" do
|
334
|
-
type =
|
335
|
-
expect(described_class.from_typed("test",
|
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
|
336
585
|
end
|
586
|
+
end
|
587
|
+
end
|
337
588
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
value
|
589
|
+
describe DBus::Data::Variant do
|
590
|
+
describe ".from_typed" do
|
591
|
+
it "creates new instance from given object and type" do
|
592
|
+
type = DBus.type(T::VARIANT)
|
593
|
+
value = described_class.from_typed("test", type: type)
|
594
|
+
expect(value).to be_a(described_class)
|
344
595
|
expect(value.type.to_s).to eq "v"
|
345
596
|
expect(value.member_type.to_s).to eq "s"
|
346
597
|
end
|
347
598
|
end
|
348
|
-
end
|
349
599
|
|
350
|
-
|
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) }
|
351
635
|
end
|
352
636
|
end
|
353
637
|
end
|
@@ -29,6 +29,13 @@ describe DBus::PacketMarshaller do
|
|
29
29
|
subject.append(signature, t.val)
|
30
30
|
expect(subject.packet).to eq(expected)
|
31
31
|
end
|
32
|
+
|
33
|
+
it "writes a '#{signature}' with typed value #{t.val.inspect} (#{endianness})" do
|
34
|
+
subject = described_class.new(endianness: endianness)
|
35
|
+
typed_val = DBus::Data.make_typed(signature, t.val)
|
36
|
+
subject.append(signature, typed_val)
|
37
|
+
expect(subject.packet).to eq(expected)
|
38
|
+
end
|
32
39
|
end
|
33
40
|
end
|
34
41
|
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/property_spec.rb
CHANGED
@@ -4,6 +4,14 @@
|
|
4
4
|
require_relative "spec_helper"
|
5
5
|
require "dbus"
|
6
6
|
|
7
|
+
# FIXME: factor out DBus::TestFixtures::Value in spec_helper
|
8
|
+
require "ostruct"
|
9
|
+
require "yaml"
|
10
|
+
|
11
|
+
data_dir = File.expand_path("data", __dir__)
|
12
|
+
marshall_yaml_s = File.read("#{data_dir}/marshall.yaml")
|
13
|
+
marshall_yaml = YAML.safe_load(marshall_yaml_s)
|
14
|
+
|
7
15
|
describe "PropertyTest" do
|
8
16
|
before(:each) do
|
9
17
|
@session_bus = DBus::ASessionBus.new
|
@@ -155,7 +163,7 @@ describe "PropertyTest" do
|
|
155
163
|
end
|
156
164
|
end
|
157
165
|
|
158
|
-
context "
|
166
|
+
context "a dict-typed property" do
|
159
167
|
it "gets read as a hash" do
|
160
168
|
val = @iface["MyDict"]
|
161
169
|
expect(val).to eq({
|
@@ -164,12 +172,50 @@ describe "PropertyTest" do
|
|
164
172
|
"three" => [3, 3, 3]
|
165
173
|
})
|
166
174
|
end
|
175
|
+
|
176
|
+
it "Get returns the correctly typed value (check with dbus-send)" do
|
177
|
+
cmd = "dbus-send --print-reply " \
|
178
|
+
"--dest=org.ruby.service " \
|
179
|
+
"/org/ruby/MyInstance " \
|
180
|
+
"org.freedesktop.DBus.Properties.Get " \
|
181
|
+
"string:org.ruby.SampleInterface " \
|
182
|
+
"string:MyDict"
|
183
|
+
reply = `#{cmd}`
|
184
|
+
# a bug about variant nesting lead to a "variant variant int32 1" value
|
185
|
+
match_rx = /variant \s+ array \s \[ \s+
|
186
|
+
dict \s entry\( \s+
|
187
|
+
string \s "one" \s+
|
188
|
+
variant \s+ int32 \s 1 \s+
|
189
|
+
\)/x
|
190
|
+
expect(reply).to match(match_rx)
|
191
|
+
end
|
167
192
|
end
|
168
193
|
|
169
194
|
context "a variant-typed property" do
|
170
195
|
it "gets read at all" do
|
171
|
-
|
196
|
+
obj = @svc.object("/org/ruby/MyDerivedInstance")
|
197
|
+
iface = obj["org.ruby.SampleInterface"]
|
198
|
+
val = iface["MyVariant"]
|
172
199
|
expect(val).to eq([42, 43])
|
173
200
|
end
|
174
201
|
end
|
202
|
+
|
203
|
+
context "marshall.yaml round-trip via a VARIANT property" do
|
204
|
+
marshall_yaml.each do |test|
|
205
|
+
t = OpenStruct.new(test)
|
206
|
+
next if t.val.nil?
|
207
|
+
|
208
|
+
# Round trips do not work yet because the properties
|
209
|
+
# must present a plain Ruby value so the exact D-Bus type is lost.
|
210
|
+
# Round trips will work once users can declare accepting DBus::Data
|
211
|
+
# in properties and method arguments.
|
212
|
+
it "Sets #{t.sig.inspect}:#{t.val.inspect} and Gets something back" do
|
213
|
+
before = DBus::Data.make_typed(t.sig, t.val)
|
214
|
+
expect { @iface["MyVariant"] = before }.to_not raise_error
|
215
|
+
expect { _after = @iface["MyVariant"] }.to_not raise_error
|
216
|
+
# round-trip:
|
217
|
+
# expect(after).to eq(before.value)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
175
221
|
end
|
data/spec/service_newapi.rb
CHANGED
@@ -107,10 +107,10 @@ class Test < DBus::Object
|
|
107
107
|
end
|
108
108
|
dbus_reader :explosive, "s"
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
dbus_attr_accessor :my_struct, "(sss)"
|
111
|
+
dbus_attr_accessor :my_array, "aq"
|
112
|
+
dbus_attr_accessor :my_dict, "a{sv}"
|
113
|
+
dbus_attr_accessor :my_variant, "v"
|
114
114
|
end
|
115
115
|
|
116
116
|
# closing and reopening the same interface
|