ruby-dbus 0.18.0.beta4 → 0.18.0.beta7
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 +40 -0
- data/VERSION +1 -1
- data/doc/Reference.md +13 -4
- data/lib/dbus/data.rb +229 -152
- data/lib/dbus/introspect.rb +13 -3
- data/lib/dbus/marshall.rb +12 -6
- data/lib/dbus/proxy_object_factory.rb +2 -0
- data/lib/dbus/proxy_object_interface.rb +37 -9
- data/lib/dbus/type.rb +146 -16
- data/lib/dbus/xml.rb +4 -0
- data/spec/data_spec.rb +367 -47
- data/spec/packet_unmarshaller_spec.rb +2 -16
- data/spec/property_spec.rb +50 -3
- data/spec/service_newapi.rb +4 -0
- 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
|
@@ -64,7 +193,7 @@ RSpec.shared_examples "constructor rejects values from this list" do |bad_list|
|
|
64
193
|
describe "#initialize" do
|
65
194
|
bad_list.each do |(value, exc_class, msg_substr)|
|
66
195
|
it "rejects #{value.inspect} with #{exc_class}: #{msg_substr}" do
|
67
|
-
msg_re = Regexp.new(Regexp.quote(msg_substr))
|
196
|
+
msg_re = Regexp.try_convert(msg_substr) || Regexp.new(Regexp.quote(msg_substr))
|
68
197
|
expect { described_class.new(value) }.to raise_error(exc_class, msg_re)
|
69
198
|
end
|
70
199
|
end
|
@@ -75,7 +204,7 @@ RSpec.shared_examples "constructor (kwargs) rejects values" do |bad_list|
|
|
75
204
|
describe "#initialize" do
|
76
205
|
bad_list.each do |(value, kwargs_hash, exc_class, msg_substr)|
|
77
206
|
it "rejects #{value.inspect}, #{kwargs_hash.inspect} with #{exc_class}: #{msg_substr}" do
|
78
|
-
msg_re = Regexp.new(Regexp.quote(msg_substr))
|
207
|
+
msg_re = Regexp.try_convert(msg_substr) || Regexp.new(Regexp.quote(msg_substr))
|
79
208
|
expect { described_class.new(value, **kwargs_hash) }.to raise_error(exc_class, msg_re)
|
80
209
|
end
|
81
210
|
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
|
|
@@ -244,29 +387,43 @@ describe DBus::Data do
|
|
244
387
|
|
245
388
|
describe "containers" do
|
246
389
|
describe DBus::Data::Array do
|
390
|
+
aq = DBus::Data::Array.new([1, 2, 3], type: "aq")
|
391
|
+
|
247
392
|
good = [
|
248
|
-
|
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)], { member_type: "q" }]
|
393
|
+
[[1, 2, 3], { type: "aq" }],
|
394
|
+
[[1, 2, 3], { type: T::Array[T::UINT16] }],
|
395
|
+
[[1, 2, 3], { type: T::Array["q"] }],
|
396
|
+
[[DBus::Data::UInt16.new(1), DBus::Data::UInt16.new(2), DBus::Data::UInt16.new(3)], { type: T::Array["q"] }]
|
253
397
|
# TODO: others
|
254
398
|
]
|
255
399
|
|
256
400
|
bad = [
|
257
401
|
# undesirable type guessing
|
258
|
-
|
259
|
-
|
260
|
-
|
402
|
+
[[1, 2, 3], { type: nil }, ArgumentError, /Expecting DBus::Type.*got nil/],
|
403
|
+
[[1, 2, 3], { type: "!" }, DBus::Type::SignatureException, "Unknown type code"],
|
404
|
+
[aq, { type: "q" }, ArgumentError, "Expecting \"a\""],
|
405
|
+
[aq, { type: "ao" }, ArgumentError,
|
406
|
+
"Specified type is ARRAY: [OBJECT_PATH] but value type is ARRAY: [UINT16]"]
|
407
|
+
# TODO: how to handle these?
|
408
|
+
# [{1 => 2, 3 => 4}, { type: "aq" }, ArgumentError, "?"],
|
409
|
+
# [/i am not an array/, { type: "aq" }, ArgumentError, "?"],
|
261
410
|
]
|
262
411
|
|
412
|
+
include_examples "#== and #eql? work for container types (inequal)",
|
413
|
+
[1, 2, 3], { type: "aq" },
|
414
|
+
[3, 2, 1], { type: "aq" }
|
415
|
+
|
416
|
+
include_examples "#== and #eql? work for container types (inequal)",
|
417
|
+
[[1, 2, 3]], { type: "aaq" },
|
418
|
+
[[3, 2, 1]], { type: "aaq" }
|
419
|
+
|
263
420
|
include_examples "constructor (kwargs) accepts values", good
|
264
421
|
include_examples "constructor (kwargs) rejects values", bad
|
265
422
|
|
266
423
|
describe ".from_typed" do
|
267
424
|
it "creates new instance from given object and type" do
|
268
|
-
type =
|
269
|
-
expect(described_class.from_typed(["test", "lest"],
|
425
|
+
type = T::Array[String]
|
426
|
+
expect(described_class.from_typed(["test", "lest"], type: type)).to be_a(described_class)
|
270
427
|
end
|
271
428
|
end
|
272
429
|
end
|
@@ -274,7 +431,7 @@ describe DBus::Data do
|
|
274
431
|
describe DBus::Data::Struct do
|
275
432
|
three_words = ::Struct.new(:a, :b, :c)
|
276
433
|
|
277
|
-
qqq = [
|
434
|
+
qqq = T::Struct[T::UINT16, T::UINT16, T::UINT16]
|
278
435
|
integers = [1, 2, 3]
|
279
436
|
uints = [DBus::Data::UInt16.new(1), DBus::Data::UInt16.new(2), DBus::Data::UInt16.new(3)]
|
280
437
|
|
@@ -291,63 +448,226 @@ describe DBus::Data do
|
|
291
448
|
# TODO: also check data ownership: reasonable to own the data?
|
292
449
|
# can make it explicit?
|
293
450
|
good = [
|
294
|
-
# from plain array; various
|
295
|
-
[integers, {
|
296
|
-
[integers, {
|
297
|
-
[integers, {
|
451
|
+
# from plain array; various *type* styles
|
452
|
+
[integers, { type: DBus.type("(qqq)") }],
|
453
|
+
[integers, { type: T::Struct["q", "q", "q"] }],
|
454
|
+
[integers, { type: T::Struct[T::UINT16, T::UINT16, T::UINT16] }],
|
455
|
+
[integers, { type: T::Struct[*DBus.types("qqq")] }],
|
298
456
|
# plain array of data
|
299
|
-
[uints, {
|
457
|
+
[uints, { type: qqq }],
|
300
458
|
# ::Struct
|
301
|
-
[three_words.new(*integers), {
|
302
|
-
[three_words.new(*uints), {
|
459
|
+
[three_words.new(*integers), { type: qqq }],
|
460
|
+
[three_words.new(*uints), { type: qqq }]
|
303
461
|
# TODO: others
|
304
462
|
]
|
305
463
|
|
464
|
+
# check these only when canonicalizing @value, because that will
|
465
|
+
# type-check the value deeply
|
306
466
|
_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
467
|
# STRUCT specific: member count mismatch
|
314
|
-
[[1, 2], {
|
315
|
-
[[1, 2, 3, 4], {
|
468
|
+
[[1, 2], { type: qqq }, ArgumentError, "???"],
|
469
|
+
[[1, 2, 3, 4], { type: qqq }, ArgumentError, "???"]
|
316
470
|
# TODO: others
|
317
471
|
]
|
318
472
|
|
473
|
+
include_examples "#== and #eql? work for container types (inequal)",
|
474
|
+
[1, 2, 3], { type: qqq },
|
475
|
+
[3, 2, 1], { type: qqq }
|
476
|
+
|
477
|
+
include_examples "#== and #eql? work for container types (equal)",
|
478
|
+
three_words.new(*integers), { type: qqq },
|
479
|
+
[1, 2, 3], { type: qqq }
|
480
|
+
|
319
481
|
include_examples "constructor (kwargs) accepts values", good
|
320
482
|
# include_examples "constructor (kwargs) rejects values", bad
|
321
483
|
|
322
484
|
describe ".from_typed" do
|
323
485
|
it "creates new instance from given object and type" do
|
324
|
-
type =
|
325
|
-
expect(described_class.from_typed(["test", "lest"].freeze,
|
486
|
+
type = T::Struct[T::STRING, T::STRING]
|
487
|
+
expect(described_class.from_typed(["test", "lest"].freeze, type: type))
|
488
|
+
.to be_a(described_class)
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
describe "#initialize" do
|
493
|
+
it "converts type to Type" do
|
494
|
+
value = [1, 2, 3]
|
495
|
+
type = "(uuu)"
|
496
|
+
result = described_class.new(value, type: type)
|
497
|
+
expect(result.type).to be_a DBus::Type
|
498
|
+
end
|
499
|
+
|
500
|
+
it "checks that type matches class" do
|
501
|
+
value = [1, 2, 3]
|
502
|
+
type = T::Array[T::INT32]
|
503
|
+
expect { described_class.new(value, type: type) }
|
504
|
+
.to raise_error(ArgumentError, /Expecting "r"/)
|
505
|
+
end
|
506
|
+
|
507
|
+
it "checks type of a Data::Struct value" do
|
508
|
+
value1 = [1, 2, 3]
|
509
|
+
type1 = "(uuu)"
|
510
|
+
result1 = described_class.new(value1, type: type1)
|
511
|
+
|
512
|
+
value2 = result1
|
513
|
+
type2 = "(xxx)"
|
514
|
+
expect { described_class.new(value2, type: type2) }
|
515
|
+
.to raise_error(ArgumentError, /value type is STRUCT.*UINT32/)
|
516
|
+
end
|
517
|
+
|
518
|
+
it "checks that size of type and value match" do
|
519
|
+
value = [1, 2, 3, 4]
|
520
|
+
type = "(uuu)"
|
521
|
+
expect { described_class.new(value, type: type) }
|
522
|
+
.to raise_error(ArgumentError, /type has 3 members.*value has 4 members/)
|
523
|
+
end
|
524
|
+
|
525
|
+
it "converts value to ::Array of Data::Base" do
|
526
|
+
value = three_words.new(*integers)
|
527
|
+
type = T::Struct[T::INT32, T::INT32, T::INT32]
|
528
|
+
result = described_class.new(value, type: type)
|
529
|
+
|
530
|
+
expect(result.exact_value).to be_an(::Array)
|
531
|
+
expect(result.exact_value[0]).to be_a(DBus::Data::Base)
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
describe DBus::Data::DictEntry do
|
537
|
+
describe ".from_typed" do
|
538
|
+
it "creates new instance from given object and type" do
|
539
|
+
type = T::Hash[String, T::INT16].child
|
540
|
+
expect(described_class.from_typed(["test", 12], type: type))
|
326
541
|
.to be_a(described_class)
|
327
542
|
end
|
328
543
|
end
|
544
|
+
|
545
|
+
describe "#initialize" do
|
546
|
+
it "checks that type matches class" do
|
547
|
+
value = [1, 2]
|
548
|
+
type = T::Array[T::INT32]
|
549
|
+
|
550
|
+
expect { described_class.new(value, type: type) }
|
551
|
+
.to raise_error(ArgumentError, /Expecting "e"/)
|
552
|
+
end
|
553
|
+
|
554
|
+
it "checks type of a Data::DictEntry value" do
|
555
|
+
value1 = [1, 2]
|
556
|
+
type1 = T::Hash[T::UINT32, T::UINT32].child
|
557
|
+
result1 = described_class.new(value1, type: type1)
|
558
|
+
|
559
|
+
value2 = result1
|
560
|
+
type2 = T::Hash[T::UINT64, T::UINT64].child
|
561
|
+
expect { described_class.new(value2, type: type2) }
|
562
|
+
.to raise_error(ArgumentError, /value type is DICT_ENTRY.*UINT32/)
|
563
|
+
end
|
564
|
+
|
565
|
+
it "checks that size of type and value match" do
|
566
|
+
value = [1, 2, 3]
|
567
|
+
type = T::Hash[T::UINT32, T::UINT32].child
|
568
|
+
expect { described_class.new(value, type: type) }
|
569
|
+
.to raise_error(ArgumentError, /type has 2 members.*value has 3 members/)
|
570
|
+
end
|
571
|
+
|
572
|
+
it "converts value to ::Array of Data::Base" do
|
573
|
+
two_words = ::Struct.new(:k, :v)
|
574
|
+
value = two_words.new(1, 2)
|
575
|
+
type = T::Hash[T::UINT32, T::UINT32].child
|
576
|
+
result = described_class.new(value, type: type)
|
577
|
+
|
578
|
+
expect(result.exact_value).to be_an(::Array)
|
579
|
+
expect(result.exact_value[0]).to be_a(DBus::Data::Base)
|
580
|
+
end
|
581
|
+
|
582
|
+
it "takes a plain value" do
|
583
|
+
input = ["test", 23]
|
584
|
+
|
585
|
+
type = T::Hash[String, T::INT16].child
|
586
|
+
value = described_class.new(input, type: type)
|
587
|
+
|
588
|
+
expect(value).to be_a(described_class)
|
589
|
+
expect(value.type.to_s).to eq "{sn}"
|
590
|
+
expect(value.value).to eql input
|
591
|
+
end
|
592
|
+
end
|
329
593
|
end
|
330
594
|
|
331
595
|
describe DBus::Data::Variant do
|
332
596
|
describe ".from_typed" do
|
333
597
|
it "creates new instance from given object and type" do
|
334
|
-
type = DBus
|
335
|
-
|
598
|
+
type = DBus.type(T::VARIANT)
|
599
|
+
value = described_class.from_typed("test", type: type)
|
600
|
+
expect(value).to be_a(described_class)
|
601
|
+
expect(value.type.to_s).to eq "v"
|
602
|
+
expect(value.member_type.to_s).to eq "s"
|
336
603
|
end
|
604
|
+
end
|
605
|
+
|
606
|
+
describe "#initialize" do
|
607
|
+
it "takes a plain value" do
|
608
|
+
input = 42
|
337
609
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
# So it must offer the member_types parameter, which is misleading
|
342
|
-
# for a Variant
|
343
|
-
value = described_class.from_typed("test", member_types: [type])
|
610
|
+
type = DBus.type(T::INT16)
|
611
|
+
value = described_class.new(input, member_type: type)
|
612
|
+
expect(value).to be_a(described_class)
|
344
613
|
expect(value.type.to_s).to eq "v"
|
345
|
-
expect(value.member_type.to_s).to eq "
|
614
|
+
expect(value.member_type.to_s).to eq "n"
|
615
|
+
expect(value.value).to eq 42
|
616
|
+
end
|
617
|
+
|
618
|
+
# FIXME: verify that @value has the correct class
|
619
|
+
it "takes an exact value" do
|
620
|
+
input = DBus::Data::Int16.new(42)
|
621
|
+
|
622
|
+
type = DBus.type(T::INT16)
|
623
|
+
value = described_class.new(input, member_type: type)
|
624
|
+
expect(value).to be_a(described_class)
|
625
|
+
expect(value.type.to_s).to eq "v"
|
626
|
+
expect(value.member_type.to_s).to eq "n"
|
627
|
+
expect(value.value).to eq 42
|
628
|
+
end
|
629
|
+
|
630
|
+
it "checks the type of the exact value" do
|
631
|
+
input = DBus::Data::UInt16.new(42)
|
632
|
+
|
633
|
+
type = DBus.type(T::INT16)
|
634
|
+
expect { described_class.new(input, member_type: type) }
|
635
|
+
.to raise_error(ArgumentError, /Variant type n does not match value type q/)
|
346
636
|
end
|
347
637
|
end
|
348
|
-
end
|
349
638
|
|
350
|
-
|
639
|
+
include_examples "#== and #eql? work for container types (1 value)",
|
640
|
+
"/foo", { member_type: DBus.type(T::STRING) }
|
641
|
+
|
642
|
+
describe "DBus.variant compatibility" do
|
643
|
+
let(:v) { DBus.variant("o", "/foo") }
|
644
|
+
|
645
|
+
describe "#[]" do
|
646
|
+
it "returns the type for 0" do
|
647
|
+
expect(v[0]).to eq DBus.type(DBus::Type::OBJECT_PATH)
|
648
|
+
end
|
649
|
+
|
650
|
+
it "returns the value for 1" do
|
651
|
+
expect(v[1]).to eq DBus::ObjectPath.new("/foo")
|
652
|
+
end
|
653
|
+
|
654
|
+
it "returns an error for other indices" do
|
655
|
+
expect { v[2] }.to raise_error(ArgumentError, /DBus.variant can only be indexed with 0 or 1/)
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
659
|
+
describe "#first" do
|
660
|
+
it "returns the type" do
|
661
|
+
expect(v.first).to eq DBus.type(DBus::Type::OBJECT_PATH)
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
665
|
+
describe "#last" do
|
666
|
+
it "returns the value" do
|
667
|
+
expect(v.last).to eq DBus::ObjectPath.new("/foo")
|
668
|
+
end
|
669
|
+
end
|
670
|
+
end
|
351
671
|
end
|
352
672
|
end
|
353
673
|
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
|