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.
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 eq(min)
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 eq(max)
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 eq(plain)
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 eq(plain)
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).value).to eq(value)
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).value).to eq(value)
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
- # [[1, 2, 3], member_type: nil],
249
- [[1, 2, 3], { member_type: "q" }],
250
- [[1, 2, 3], { member_type: DBus::Type::UINT16 }],
251
- [[1, 2, 3], { member_type: DBus.type("q") }],
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
- ## [[1, 2, 3], { member_type: nil }, DBus::InvalidPacketException, "Unknown type code"],
259
- ## [[1, 2, 3], { member_type: "!" }, DBus::InvalidPacketException, "Unknown type code"]
260
- # TODO: others
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 = DBus::Type.new("s")
269
- expect(described_class.from_typed(["test", "lest"], member_types: [type])).to be_a(described_class)
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 = ["q", "q", "q"]
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 m_t styles
295
- [integers, { member_types: ["q", "q", "q"] }],
296
- [integers, { member_types: [DBus::Type::UINT16, DBus::Type::UINT16, DBus::Type::UINT16] }],
297
- [integers, { member_types: DBus.types("qqq") }],
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, { member_types: DBus.types("qqq") }],
457
+ [uints, { type: qqq }],
300
458
  # ::Struct
301
- [three_words.new(*integers), { member_types: qqq }],
302
- [three_words.new(*uints), { member_types: qqq }]
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], { member_types: DBus.types("qqq") }, ArgumentError, "???"],
315
- [[1, 2, 3, 4], { member_types: DBus.types("qqq") }, ArgumentError, "???"]
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 = DBus::Type.new("s")
325
- expect(described_class.from_typed(["test", "lest"].freeze, member_types: [type, type]))
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::Type.new("s")
335
- expect(described_class.from_typed("test", member_types: [type])).to be_a(described_class)
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
- it "ignores the member_types argument" do
339
- type = DBus::Type.new("s")
340
- # Base.from_typed is a generic interface with a fixed signature;
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 "s"
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
- describe DBus::Data::DictEntry do
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
- if expected.is_a?(Hash)
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
- if expected.is_a?(Hash)
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