ruby-dbus 0.16.0 → 0.18.1
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 +160 -0
- data/README.md +3 -5
- data/Rakefile +18 -8
- data/VERSION +1 -1
- data/doc/Reference.md +106 -7
- data/examples/doc/_extract_examples +7 -0
- data/examples/gdbus/gdbus +31 -24
- data/examples/no-introspect/nm-test.rb +2 -0
- data/examples/no-introspect/tracker-test.rb +3 -1
- data/examples/rhythmbox/playpause.rb +2 -1
- data/examples/service/call_service.rb +2 -1
- data/examples/service/complex-property.rb +21 -0
- data/examples/service/service_newapi.rb +1 -1
- data/examples/simple/call_introspect.rb +1 -0
- data/examples/simple/get_id.rb +2 -1
- data/examples/simple/properties.rb +2 -0
- data/examples/utils/listnames.rb +1 -0
- data/examples/utils/notify.rb +1 -0
- data/lib/dbus/api_options.rb +9 -0
- data/lib/dbus/auth.rb +20 -15
- data/lib/dbus/bus.rb +123 -75
- data/lib/dbus/bus_name.rb +12 -8
- data/lib/dbus/core_ext/class/attribute.rb +1 -1
- data/lib/dbus/data.rb +821 -0
- data/lib/dbus/emits_changed_signal.rb +83 -0
- data/lib/dbus/error.rb +4 -2
- data/lib/dbus/introspect.rb +132 -31
- data/lib/dbus/logger.rb +3 -1
- data/lib/dbus/marshall.rb +247 -296
- data/lib/dbus/matchrule.rb +16 -16
- data/lib/dbus/message.rb +44 -37
- data/lib/dbus/message_queue.rb +16 -10
- data/lib/dbus/object.rb +358 -24
- data/lib/dbus/object_path.rb +11 -6
- data/lib/dbus/proxy_object.rb +22 -1
- data/lib/dbus/proxy_object_factory.rb +13 -7
- data/lib/dbus/proxy_object_interface.rb +63 -30
- data/lib/dbus/raw_message.rb +91 -0
- data/lib/dbus/type.rb +318 -86
- data/lib/dbus/xml.rb +32 -17
- data/lib/dbus.rb +14 -7
- data/ruby-dbus.gemspec +7 -3
- data/spec/async_spec.rb +2 -0
- data/spec/binding_spec.rb +2 -0
- data/spec/bus_and_xml_backend_spec.rb +2 -0
- data/spec/bus_driver_spec.rb +2 -0
- data/spec/bus_name_spec.rb +3 -1
- data/spec/bus_spec.rb +2 -0
- data/spec/byte_array_spec.rb +2 -0
- data/spec/client_robustness_spec.rb +4 -2
- data/spec/data/marshall.yaml +1667 -0
- data/spec/data_spec.rb +673 -0
- data/spec/emits_changed_signal_spec.rb +58 -0
- data/spec/err_msg_spec.rb +2 -0
- data/spec/introspect_xml_parser_spec.rb +2 -0
- data/spec/introspection_spec.rb +2 -0
- data/spec/main_loop_spec.rb +3 -1
- data/spec/node_spec.rb +23 -0
- data/spec/object_path_spec.rb +3 -0
- data/spec/object_spec.rb +138 -0
- data/spec/packet_marshaller_spec.rb +41 -0
- data/spec/packet_unmarshaller_spec.rb +248 -0
- data/spec/property_spec.rb +192 -5
- data/spec/proxy_object_spec.rb +2 -0
- data/spec/server_robustness_spec.rb +2 -0
- data/spec/server_spec.rb +2 -0
- data/spec/service_newapi.rb +70 -70
- data/spec/session_bus_spec.rb +3 -1
- data/spec/session_bus_spec_manual.rb +2 -0
- data/spec/signal_spec.rb +5 -3
- data/spec/spec_helper.rb +37 -9
- data/spec/thread_safety_spec.rb +2 -0
- data/spec/tools/dbus-limited-session.conf +4 -0
- data/spec/type_spec.rb +214 -6
- data/spec/value_spec.rb +16 -1
- data/spec/variant_spec.rb +4 -2
- data/spec/zzz_quit_spec.rb +16 -0
- metadata +34 -8
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "spec_helper"
|
5
|
+
require "dbus"
|
6
|
+
|
7
|
+
describe DBus::EmitsChangedSignal do
|
8
|
+
describe "#initialize" do
|
9
|
+
it "accepts a simple value" do
|
10
|
+
expect(described_class.new(:const).value).to eq :const
|
11
|
+
end
|
12
|
+
|
13
|
+
it "avoids nil by asking the interface" do
|
14
|
+
ifc = DBus::Interface.new("org.example.Foo")
|
15
|
+
ifc.emits_changed_signal = described_class.new(:invalidates)
|
16
|
+
|
17
|
+
expect(described_class.new(nil, interface: ifc).value).to eq :invalidates
|
18
|
+
end
|
19
|
+
|
20
|
+
it "fails for unknown value" do
|
21
|
+
expect { described_class.new(:huh) }.to raise_error(ArgumentError, /Seen :huh/)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "fails for 2 nils" do
|
25
|
+
expect { described_class.new(nil, interface: nil) }.to raise_error(ArgumentError, /Both/)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#==" do
|
30
|
+
it "is true for two different objects with the same value" do
|
31
|
+
const_a = described_class.new(:const)
|
32
|
+
const_b = described_class.new(:const)
|
33
|
+
expect(const_a == const_b).to be true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#to_xml" do
|
38
|
+
it "uses a string value" do
|
39
|
+
expect(described_class.new(:const).to_xml)
|
40
|
+
.to eq " <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#to_s" do
|
45
|
+
it "uses a string value" do
|
46
|
+
expect(described_class.new(:const).to_s).to eq "const"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe DBus::Interface do
|
52
|
+
describe ".emits_changed_signal=" do
|
53
|
+
it "only allows an EmitsChangedSignal as argument" do
|
54
|
+
ifc = described_class.new("org.ruby.Interface")
|
55
|
+
expect { ifc.emits_changed_signal = :const }.to raise_error(TypeError)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/spec/err_msg_spec.rb
CHANGED
data/spec/introspection_spec.rb
CHANGED
data/spec/main_loop_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# Test the main loop
|
3
5
|
require_relative "spec_helper"
|
4
6
|
require "dbus"
|
@@ -70,7 +72,7 @@ describe "MainLoopTest" do
|
|
70
72
|
@obj.on_signal "LongTaskEnd"
|
71
73
|
end
|
72
74
|
|
73
|
-
it "tests loop quit" do
|
75
|
+
it "tests loop quit", slow: true do
|
74
76
|
test_loop_quit 1
|
75
77
|
end
|
76
78
|
|
data/spec/node_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "spec_helper"
|
5
|
+
require "dbus"
|
6
|
+
|
7
|
+
describe DBus::Node do
|
8
|
+
describe "#inspect" do
|
9
|
+
# the behavior needs improvement
|
10
|
+
it "shows the node, poorly" do
|
11
|
+
parent = described_class.new("parent")
|
12
|
+
parent.object = DBus::Object.new("/parent")
|
13
|
+
|
14
|
+
3.times do |i|
|
15
|
+
child_name = "child#{i}"
|
16
|
+
child = described_class.new(child_name)
|
17
|
+
parent[child_name] = child
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(parent.inspect).to match(/<DBus::Node [0-9a-f]+ {child0 => {},child1 => {},child2 => {}}>/)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/object_path_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require_relative "spec_helper"
|
3
5
|
require "dbus"
|
4
6
|
|
@@ -18,6 +20,7 @@ describe DBus::ObjectPath do
|
|
18
20
|
expect(described_class.valid?("/EmptyLastComponent/")).to be_falsey
|
19
21
|
expect(described_class.valid?("/Invalid Character")).to be_falsey
|
20
22
|
expect(described_class.valid?("/Invalid-Character")).to be_falsey
|
23
|
+
expect(described_class.valid?("/InválídCháráctér")).to be_falsey
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
data/spec/object_spec.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "spec_helper"
|
5
|
+
require "dbus"
|
6
|
+
|
7
|
+
class ObjectTest < DBus::Object
|
8
|
+
T = DBus::Type unless const_defined? "T"
|
9
|
+
|
10
|
+
dbus_interface "org.ruby.ServerTest" do
|
11
|
+
dbus_attr_writer :write_me, T::Struct[String, String]
|
12
|
+
|
13
|
+
attr_accessor :read_only_for_dbus
|
14
|
+
|
15
|
+
dbus_reader :read_only_for_dbus, T::STRING, emits_changed_signal: :invalidates
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe DBus::Object do
|
20
|
+
describe ".dbus_attr_writer" do
|
21
|
+
describe "the declared assignment method" do
|
22
|
+
# Slightly advanced RSpec:
|
23
|
+
# https://rspec.info/documentation/3.9/rspec-expectations/RSpec/Matchers.html#satisfy-instance_method
|
24
|
+
let(:a_struct_in_a_variant) do
|
25
|
+
satisfying { |x| x.is_a?(DBus::Data::Variant) && x.member_type.to_s == "(ss)" }
|
26
|
+
# ^ This formatting keeps the matcher on a single line
|
27
|
+
# which enables RSpec to cite it if it fails, instead of saying "block".
|
28
|
+
end
|
29
|
+
|
30
|
+
it "emits PropertyChanged with correctly typed argument" do
|
31
|
+
obj = ObjectTest.new("/test")
|
32
|
+
expect(obj).to receive(:PropertiesChanged).with(
|
33
|
+
"org.ruby.ServerTest",
|
34
|
+
{
|
35
|
+
"WriteMe" => a_struct_in_a_variant
|
36
|
+
},
|
37
|
+
[]
|
38
|
+
)
|
39
|
+
# bug: call PC with simply the assigned value,
|
40
|
+
# which will need type guessing
|
41
|
+
obj.write_me = ["two", "strings"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe ".dbus_accessor" do
|
47
|
+
it "can only be used within a dbus_interface" do
|
48
|
+
expect do
|
49
|
+
ObjectTest.instance_exec do
|
50
|
+
dbus_accessor :foo, DBus::Type::STRING
|
51
|
+
end
|
52
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe ".dbus_reader" do
|
57
|
+
it "can only be used within a dbus_interface" do
|
58
|
+
expect do
|
59
|
+
ObjectTest.instance_exec do
|
60
|
+
dbus_reader :foo, DBus::Type::STRING
|
61
|
+
end
|
62
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe ".dbus_reader, when paired with attr_accessor" do
|
67
|
+
describe "the declared assignment method" do
|
68
|
+
it "emits PropertyChanged" do
|
69
|
+
obj = ObjectTest.new("/test")
|
70
|
+
expect(obj).to receive(:PropertiesChanged).with(
|
71
|
+
"org.ruby.ServerTest",
|
72
|
+
{},
|
73
|
+
["ReadOnlyForDbus"]
|
74
|
+
)
|
75
|
+
obj.read_only_for_dbus = "myvalue"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe ".dbus_writer" do
|
81
|
+
it "can only be used within a dbus_interface" do
|
82
|
+
expect do
|
83
|
+
ObjectTest.instance_exec do
|
84
|
+
dbus_writer :foo, DBus::Type::STRING
|
85
|
+
end
|
86
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe ".dbus_watcher" do
|
91
|
+
it "can only be used within a dbus_interface" do
|
92
|
+
expect do
|
93
|
+
ObjectTest.instance_exec do
|
94
|
+
dbus_watcher :foo
|
95
|
+
end
|
96
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe ".dbus_method" do
|
101
|
+
it "can only be used within a dbus_interface" do
|
102
|
+
expect do
|
103
|
+
ObjectTest.instance_exec do
|
104
|
+
dbus_method :foo do
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe ".emits_changed_signal" do
|
112
|
+
it "raises UndefinedInterface when so" do
|
113
|
+
expect { ObjectTest.emits_changed_signal = false }
|
114
|
+
.to raise_error DBus::Object::UndefinedInterface
|
115
|
+
end
|
116
|
+
|
117
|
+
it "assigns to the current interface" do
|
118
|
+
ObjectTest.instance_exec do
|
119
|
+
dbus_interface "org.ruby.Interface" do
|
120
|
+
self.emits_changed_signal = false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
ecs = ObjectTest.intfs["org.ruby.Interface"].emits_changed_signal
|
124
|
+
expect(ecs).to eq false
|
125
|
+
end
|
126
|
+
|
127
|
+
it "only can be assigned once" do
|
128
|
+
expect do
|
129
|
+
Class.new(DBus::Object) do
|
130
|
+
dbus_interface "org.ruby.Interface" do
|
131
|
+
self.emits_changed_signal = false
|
132
|
+
self.emits_changed_signal = :invalidates
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end.to raise_error(RuntimeError, /assigned more than once/)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "spec_helper"
|
5
|
+
require "dbus"
|
6
|
+
require "ostruct"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
data_dir = File.expand_path("data", __dir__)
|
10
|
+
marshall_yaml_s = File.read("#{data_dir}/marshall.yaml")
|
11
|
+
marshall_yaml = YAML.safe_load(marshall_yaml_s)
|
12
|
+
|
13
|
+
describe DBus::PacketMarshaller do
|
14
|
+
context "marshall.yaml" do
|
15
|
+
marshall_yaml.each do |test|
|
16
|
+
t = OpenStruct.new(test)
|
17
|
+
next if t.marshall == false
|
18
|
+
# skip test cases for invalid unmarshalling
|
19
|
+
next if t.val.nil?
|
20
|
+
|
21
|
+
# while the marshaller can use only native endianness, skip the other
|
22
|
+
endianness = t.end.to_sym
|
23
|
+
|
24
|
+
signature = t.sig
|
25
|
+
expected = buffer_from_yaml(t.buf)
|
26
|
+
|
27
|
+
it "writes a '#{signature}' with value #{t.val.inspect} (#{endianness})" do
|
28
|
+
subject = described_class.new(endianness: endianness)
|
29
|
+
subject.append(signature, t.val)
|
30
|
+
expect(subject.packet).to eq(expected)
|
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
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "spec_helper"
|
5
|
+
require "dbus"
|
6
|
+
require "ostruct"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
data_dir = File.expand_path("data", __dir__)
|
10
|
+
marshall_yaml_s = File.read("#{data_dir}/marshall.yaml")
|
11
|
+
marshall_yaml = YAML.safe_load(marshall_yaml_s)
|
12
|
+
|
13
|
+
# Helper to access PacketUnmarshaller internals.
|
14
|
+
# Add it to its public API?
|
15
|
+
# @param p_u [PacketUnmarshaller]
|
16
|
+
# @return [String] the binary string with unconsumed data
|
17
|
+
def remaining_buffer(p_u)
|
18
|
+
raw_msg = p_u.instance_variable_get(:@raw_msg)
|
19
|
+
raw_msg.remaining_bytes
|
20
|
+
end
|
21
|
+
|
22
|
+
RSpec.shared_examples "parses good data" do |cases|
|
23
|
+
describe "parses all the instances of good test data" do
|
24
|
+
cases.each_with_index do |(buffer, endianness, expected), i|
|
25
|
+
it "parses plain data ##{i}" do
|
26
|
+
buffer = String.new(buffer, encoding: Encoding::BINARY)
|
27
|
+
subject = described_class.new(buffer, endianness)
|
28
|
+
|
29
|
+
results = subject.unmarshall(signature, mode: :plain)
|
30
|
+
# unmarshall works on multiple signatures but we use one
|
31
|
+
expect(results).to be_an(Array)
|
32
|
+
expect(results.size).to eq(1)
|
33
|
+
result = results.first
|
34
|
+
|
35
|
+
expect(result).to eq(expected)
|
36
|
+
|
37
|
+
expect(remaining_buffer(subject)).to be_empty
|
38
|
+
end
|
39
|
+
|
40
|
+
it "parses exact data ##{i}" do
|
41
|
+
buffer = String.new(buffer, encoding: Encoding::BINARY)
|
42
|
+
subject = described_class.new(buffer, endianness)
|
43
|
+
|
44
|
+
results = subject.unmarshall(signature, mode: :exact)
|
45
|
+
# unmarshall works on multiple signatures but we use one
|
46
|
+
expect(results).to be_an(Array)
|
47
|
+
expect(results.size).to eq(1)
|
48
|
+
result = results.first
|
49
|
+
|
50
|
+
expect(result).to be_a(DBus::Data::Base)
|
51
|
+
expect(result.value).to eq(expected)
|
52
|
+
|
53
|
+
expect(remaining_buffer(subject)).to be_empty
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# this is necessary because we do an early switch on the signature
|
60
|
+
RSpec.shared_examples "reports empty data" do
|
61
|
+
it "reports empty data" do
|
62
|
+
[:big, :little].each do |endianness|
|
63
|
+
subject = described_class.new("", endianness)
|
64
|
+
expect { subject.unmarshall(signature) }.to raise_error(DBus::IncompleteBufferException)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe DBus::PacketUnmarshaller do
|
70
|
+
context "marshall.yaml" do
|
71
|
+
marshall_yaml.each do |test|
|
72
|
+
t = OpenStruct.new(test)
|
73
|
+
signature = t.sig
|
74
|
+
buffer = buffer_from_yaml(t.buf)
|
75
|
+
endianness = t.end.to_sym
|
76
|
+
|
77
|
+
# successful parse
|
78
|
+
if !t.val.nil?
|
79
|
+
expected = t.val
|
80
|
+
|
81
|
+
it "parses a '#{signature}' to get #{t.val.inspect} (plain)" do
|
82
|
+
subject = described_class.new(buffer, endianness)
|
83
|
+
results = subject.unmarshall(signature, mode: :plain)
|
84
|
+
# unmarshall works on multiple signatures but we use one
|
85
|
+
expect(results).to be_an(Array)
|
86
|
+
expect(results.size).to eq(1)
|
87
|
+
result = results.first
|
88
|
+
|
89
|
+
expect(result).to eq(expected)
|
90
|
+
expect(remaining_buffer(subject)).to be_empty
|
91
|
+
end
|
92
|
+
|
93
|
+
it "parses a '#{t.sig}' to get #{t.val.inspect} (exact)" do
|
94
|
+
subject = described_class.new(buffer, endianness)
|
95
|
+
results = subject.unmarshall(signature, mode: :exact)
|
96
|
+
# unmarshall works on multiple signatures but we use one
|
97
|
+
expect(results).to be_an(Array)
|
98
|
+
expect(results.size).to eq(1)
|
99
|
+
result = results.first
|
100
|
+
|
101
|
+
expect(result).to be_a(DBus::Data::Base)
|
102
|
+
expect(result.value).to eq(expected)
|
103
|
+
|
104
|
+
expect(remaining_buffer(subject)).to be_empty
|
105
|
+
end
|
106
|
+
elsif t.exc
|
107
|
+
next if t.unmarshall == false
|
108
|
+
|
109
|
+
exc_class = DBus.const_get(t.exc)
|
110
|
+
msg_re = Regexp.new(Regexp.escape(t.msg))
|
111
|
+
|
112
|
+
# TODO: InvalidPacketException is never rescued.
|
113
|
+
# The other end is sending invalid data. Can we do better than crashing?
|
114
|
+
# When we can test with peer connections, try it out.
|
115
|
+
it "parses a '#{signature}' to report a #{t.exc}" do
|
116
|
+
subject = described_class.new(buffer, endianness)
|
117
|
+
expect { subject.unmarshall(signature, mode: :plain) }.to raise_error(exc_class, msg_re)
|
118
|
+
|
119
|
+
subject = described_class.new(buffer, endianness)
|
120
|
+
expect { subject.unmarshall(signature, mode: :exact) }.to raise_error(exc_class, msg_re)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "BYTEs" do
|
127
|
+
let(:signature) { "y" }
|
128
|
+
include_examples "reports empty data"
|
129
|
+
end
|
130
|
+
|
131
|
+
context "BOOLEANs" do
|
132
|
+
let(:signature) { "b" }
|
133
|
+
include_examples "reports empty data"
|
134
|
+
end
|
135
|
+
|
136
|
+
context "INT16s" do
|
137
|
+
let(:signature) { "n" }
|
138
|
+
include_examples "reports empty data"
|
139
|
+
end
|
140
|
+
|
141
|
+
context "UINT16s" do
|
142
|
+
let(:signature) { "q" }
|
143
|
+
include_examples "reports empty data"
|
144
|
+
end
|
145
|
+
|
146
|
+
context "INT32s" do
|
147
|
+
let(:signature) { "i" }
|
148
|
+
include_examples "reports empty data"
|
149
|
+
end
|
150
|
+
|
151
|
+
context "UINT32s" do
|
152
|
+
let(:signature) { "u" }
|
153
|
+
include_examples "reports empty data"
|
154
|
+
end
|
155
|
+
|
156
|
+
context "UNIX_FDs" do
|
157
|
+
let(:signature) { "h" }
|
158
|
+
include_examples "reports empty data"
|
159
|
+
end
|
160
|
+
|
161
|
+
context "INT64s" do
|
162
|
+
let(:signature) { "x" }
|
163
|
+
include_examples "reports empty data"
|
164
|
+
end
|
165
|
+
|
166
|
+
context "UINT64s" do
|
167
|
+
let(:signature) { "t" }
|
168
|
+
include_examples "reports empty data"
|
169
|
+
end
|
170
|
+
|
171
|
+
context "DOUBLEs" do
|
172
|
+
let(:signature) { "d" }
|
173
|
+
# See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
|
174
|
+
# for binary representations
|
175
|
+
# TODO: figure out IEEE754 comparisons
|
176
|
+
good = [
|
177
|
+
# But == cant distinguish -0.0
|
178
|
+
["\x00\x00\x00\x00\x00\x00\x00\x80", :little, -0.0],
|
179
|
+
# But NaN == NaN is false!
|
180
|
+
# ["\xff\xff\xff\xff\xff\xff\xff\xff", :little, Float::NAN],
|
181
|
+
["\x80\x00\x00\x00\x00\x00\x00\x00", :big, -0.0]
|
182
|
+
# ["\xff\xff\xff\xff\xff\xff\xff\xff", :big, Float::NAN]
|
183
|
+
]
|
184
|
+
include_examples "parses good data", good
|
185
|
+
include_examples "reports empty data"
|
186
|
+
end
|
187
|
+
|
188
|
+
context "STRINGs" do
|
189
|
+
let(:signature) { "s" }
|
190
|
+
include_examples "reports empty data"
|
191
|
+
end
|
192
|
+
|
193
|
+
context "OBJECT_PATHs" do
|
194
|
+
let(:signature) { "o" }
|
195
|
+
include_examples "reports empty data"
|
196
|
+
end
|
197
|
+
|
198
|
+
context "SIGNATUREs" do
|
199
|
+
let(:signature) { "g" }
|
200
|
+
include_examples "reports empty data"
|
201
|
+
end
|
202
|
+
|
203
|
+
context "ARRAYs" do
|
204
|
+
context "of BYTEs" do
|
205
|
+
let(:signature) { "ay" }
|
206
|
+
include_examples "reports empty data"
|
207
|
+
end
|
208
|
+
|
209
|
+
context "of UINT64s" do
|
210
|
+
let(:signature) { "at" }
|
211
|
+
include_examples "reports empty data"
|
212
|
+
end
|
213
|
+
|
214
|
+
context "of STRUCT of 2 UINT16s" do
|
215
|
+
let(:signature) { "a(qq)" }
|
216
|
+
include_examples "reports empty data"
|
217
|
+
end
|
218
|
+
|
219
|
+
context "of DICT_ENTRIES" do
|
220
|
+
let(:signature) { "a{yq}" }
|
221
|
+
include_examples "reports empty data"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "STRUCTs" do
|
226
|
+
# TODO: this is invalid but does not raise
|
227
|
+
context "(generic 'r' struct)" do
|
228
|
+
let(:signature) { "r" }
|
229
|
+
end
|
230
|
+
|
231
|
+
context "of two shorts" do
|
232
|
+
let(:signature) { "(qq)" }
|
233
|
+
include_examples "reports empty data"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# makes sense here? or in array? remember invalid sigs are rejected elsewhere
|
238
|
+
context "DICT_ENTRYs" do
|
239
|
+
context "(generic 'e' dict_entry)" do
|
240
|
+
let(:signature) { "e" }
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "VARIANTs" do
|
245
|
+
let(:signature) { "v" }
|
246
|
+
include_examples "reports empty data"
|
247
|
+
end
|
248
|
+
end
|