ruby-dbus 0.16.0 → 0.25.0
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 +288 -3
- data/README.md +3 -5
- data/Rakefile +27 -12
- data/VERSION +1 -1
- data/doc/Reference.md +109 -10
- data/examples/doc/_extract_examples +7 -0
- data/examples/no-bus/pulseaudio.rb +50 -0
- 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 +3 -3
- data/examples/simple/call_introspect.rb +1 -0
- data/examples/simple/get_id.rb +6 -3
- data/examples/simple/properties.rb +2 -0
- data/examples/utils/listnames.rb +10 -1
- data/examples/utils/notify.rb +1 -0
- data/lib/dbus/api_options.rb +9 -0
- data/lib/dbus/auth.rb +307 -217
- data/lib/dbus/bus.rb +155 -588
- data/lib/dbus/bus_name.rb +12 -8
- data/lib/dbus/connection.rb +363 -0
- 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 +133 -31
- data/lib/dbus/logger.rb +6 -3
- data/lib/dbus/main.rb +66 -0
- data/lib/dbus/marshall.rb +247 -296
- data/lib/dbus/matchrule.rb +16 -16
- data/lib/dbus/message.rb +66 -57
- data/lib/dbus/message_queue.rb +40 -25
- data/lib/dbus/node_tree.rb +105 -0
- data/lib/dbus/object.rb +442 -33
- data/lib/dbus/object_manager.rb +61 -0
- data/lib/dbus/object_path.rb +11 -6
- data/lib/dbus/object_server.rb +149 -0
- data/lib/dbus/org.freedesktop.DBus.xml +97 -0
- data/lib/dbus/platform.rb +26 -0
- data/lib/dbus/proxy_object.rb +30 -11
- data/lib/dbus/proxy_object_factory.rb +13 -7
- data/lib/dbus/proxy_object_interface.rb +63 -30
- data/lib/dbus/proxy_service.rb +107 -0
- data/lib/dbus/raw_message.rb +91 -0
- data/lib/dbus/type.rb +319 -86
- data/lib/dbus/xml.rb +40 -19
- data/lib/dbus.rb +28 -17
- data/ruby-dbus.gemspec +13 -6
- data/spec/async_spec.rb +2 -0
- data/spec/auth_spec.rb +225 -0
- data/spec/binding_spec.rb +2 -0
- data/spec/bus_and_xml_backend_spec.rb +5 -1
- data/spec/bus_connection_spec.rb +93 -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/connection_spec.rb +37 -0
- data/spec/coverage_helper.rb +39 -0
- data/spec/data/marshall.yaml +1667 -0
- data/spec/data_spec.rb +673 -0
- data/spec/dbus_spec.rb +22 -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 +17 -1
- data/spec/message_spec.rb +21 -0
- data/spec/mock-service/cockpit-dbustests.rb +29 -0
- data/spec/mock-service/com.redhat.Cockpit.DBusTests.xml +180 -0
- data/spec/mock-service/org.ruby.service.service +4 -0
- data/spec/mock-service/org.rubygems.ruby_dbus.DBusTests.service +4 -0
- data/spec/{service_newapi.rb → mock-service/spaghetti-monster.rb} +122 -75
- data/spec/node_spec.rb +65 -0
- data/spec/object_manager_spec.rb +33 -0
- data/spec/object_path_spec.rb +3 -0
- data/spec/object_server_spec.rb +138 -0
- data/spec/object_spec.rb +194 -0
- data/spec/packet_marshaller_spec.rb +41 -0
- data/spec/packet_unmarshaller_spec.rb +248 -0
- data/spec/platform_spec.rb +14 -0
- data/spec/property_spec.rb +214 -12
- data/spec/proxy_object_interface_spec.rb +35 -0
- data/spec/proxy_object_spec.rb +2 -0
- data/spec/{bus_driver_spec.rb → proxy_service_spec.rb} +15 -8
- data/spec/raw_message_spec.rb +32 -0
- data/spec/server_robustness_spec.rb +20 -6
- data/spec/session_bus_spec.rb +36 -1
- data/spec/session_bus_spec_manual.rb +2 -0
- data/spec/signal_spec.rb +16 -3
- data/spec/spec_helper.rb +25 -33
- data/spec/thread_safety_spec.rb +55 -12
- data/spec/tools/dbus-launch-simple +9 -6
- data/spec/tools/dbus-limited-session.conf +32 -0
- data/spec/tools/test_env +26 -6
- 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 +92 -20
- data/examples/gdbus/gdbus +0 -257
- data/examples/gdbus/gdbus.glade +0 -98
- data/examples/gdbus/launch.sh +0 -4
- data/spec/server_spec.rb +0 -53
- data/spec/tools/test_server +0 -39
data/spec/node_spec.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
|
|
24
|
+
describe "#descendant_objects" do
|
|
25
|
+
let(:manager_path) { "/org/example/FooManager" }
|
|
26
|
+
let(:child_paths) do
|
|
27
|
+
[
|
|
28
|
+
# NOTE: "/org/example/FooManager/good"
|
|
29
|
+
# is a path under a managed object but there is no object there
|
|
30
|
+
"/org/example/FooManager/good/1",
|
|
31
|
+
"/org/example/FooManager/good/2",
|
|
32
|
+
"/org/example/FooManager/good/3",
|
|
33
|
+
"/org/example/FooManager/bad/1",
|
|
34
|
+
"/org/example/FooManager/bad/2"
|
|
35
|
+
]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
let(:non_child_paths) do
|
|
39
|
+
[
|
|
40
|
+
"/org/example/BarManager/good/1",
|
|
41
|
+
"/org/example/BarManager/good/2"
|
|
42
|
+
]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "on the bus" do
|
|
46
|
+
let(:bus) { DBus::ASessionBus.new }
|
|
47
|
+
let(:service) { bus.object_server }
|
|
48
|
+
|
|
49
|
+
before do
|
|
50
|
+
service.export(DBus::Object.new(manager_path))
|
|
51
|
+
non_child_paths.each do |p|
|
|
52
|
+
service.export(DBus::Object.new(p))
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "returns just the descendants of the specified objects" do
|
|
57
|
+
child_exported_objects = child_paths.map { |p| DBus::Object.new(p) }
|
|
58
|
+
child_exported_objects.each { |obj| service.export(obj) }
|
|
59
|
+
|
|
60
|
+
node = service.get_node(manager_path, create: false)
|
|
61
|
+
expect(node.descendant_objects).to eq child_exported_objects
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env rspec
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative "spec_helper"
|
|
5
|
+
require "dbus"
|
|
6
|
+
|
|
7
|
+
describe DBus::ObjectManager do
|
|
8
|
+
describe "GetManagedObjects" do
|
|
9
|
+
let(:bus) { DBus::ASessionBus.new }
|
|
10
|
+
let(:service) { bus["org.ruby.service"] }
|
|
11
|
+
let(:obj) { service["/org/ruby/MyInstance"] }
|
|
12
|
+
let(:parent_iface) { obj["org.ruby.TestParent"] }
|
|
13
|
+
let(:om_iface) { obj["org.freedesktop.DBus.ObjectManager"] }
|
|
14
|
+
|
|
15
|
+
it "returns the interfaces and properties of currently managed objects" do
|
|
16
|
+
c1_opath = parent_iface.New("child1")
|
|
17
|
+
c2_opath = parent_iface.New("child2")
|
|
18
|
+
|
|
19
|
+
parent_iface.Delete(c1_opath)
|
|
20
|
+
expected_gmo = {
|
|
21
|
+
"/org/ruby/MyInstance/child2" => {
|
|
22
|
+
"org.freedesktop.DBus.Introspectable" => {},
|
|
23
|
+
"org.freedesktop.DBus.Properties" => {},
|
|
24
|
+
"org.ruby.TestChild" => { "Name" => "Child2" }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
expect(om_iface.GetManagedObjects).to eq(expected_gmo)
|
|
28
|
+
|
|
29
|
+
parent_iface.Delete(c2_opath)
|
|
30
|
+
expect(om_iface.GetManagedObjects).to eq({})
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
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
|
|
@@ -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
|
+
describe DBus::ObjectServer do
|
|
8
|
+
let(:bus) { DBus::ASessionBus.new }
|
|
9
|
+
let(:server) { bus.object_server }
|
|
10
|
+
|
|
11
|
+
describe "#descendants_for" do
|
|
12
|
+
it "raises for not existing path" do
|
|
13
|
+
expect { server.descendants_for("/notthere") }.to raise_error(ArgumentError, /notthere doesn't exist/)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# tag_bus MEANS that the test needs a session bus
|
|
18
|
+
# tag_service MEANS that it needs a session bus with our testing services
|
|
19
|
+
|
|
20
|
+
describe "#export, #object, #[]", tag_bus: true do
|
|
21
|
+
it "object and [] return the object if it was exported" do
|
|
22
|
+
path = "/org/ruby/Foo"
|
|
23
|
+
obj = DBus::Object.new(path)
|
|
24
|
+
server.export(obj)
|
|
25
|
+
expect(server.object(path)).to be_equal(obj)
|
|
26
|
+
expect(server[path]).to be_equal(obj)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "object and [] return nil if the path was not found or has no object" do
|
|
30
|
+
path = "/org/ruby/Bar"
|
|
31
|
+
obj = DBus::Object.new(path)
|
|
32
|
+
server.export(obj)
|
|
33
|
+
|
|
34
|
+
path2 = "/org/ruby/nosuch"
|
|
35
|
+
expect(server.object(path2)).to be_nil
|
|
36
|
+
expect(server[path2]).to be_nil
|
|
37
|
+
|
|
38
|
+
path3 = "/org"
|
|
39
|
+
expect(server.object(path3)).to be_nil
|
|
40
|
+
expect(server[path3]).to be_nil
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "#export", tag_bus: true do
|
|
45
|
+
context "when exporting at a path where an object exists already" do
|
|
46
|
+
let(:path) { "/org/ruby/Same" }
|
|
47
|
+
let(:obj1) do
|
|
48
|
+
o = DBus::Object.new(path)
|
|
49
|
+
o.define_singleton_method(:which) { 1 }
|
|
50
|
+
o
|
|
51
|
+
end
|
|
52
|
+
let(:obj2) do
|
|
53
|
+
o = DBus::Object.new(path)
|
|
54
|
+
o.define_singleton_method(:which) { 2 }
|
|
55
|
+
o
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "raises an error" do
|
|
59
|
+
server.export(obj1)
|
|
60
|
+
expect { server.export(obj2) }.to raise_error(RuntimeError, /there is already an object/)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "#unexport", tag_bus: true do
|
|
66
|
+
before(:each) do
|
|
67
|
+
bus = DBus::ASessionBus.new
|
|
68
|
+
@svc = bus.object_server
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "returns the unexported leaf object" do
|
|
72
|
+
obj = DBus::Object.new "/org/ruby/Foo"
|
|
73
|
+
@svc.export obj
|
|
74
|
+
expect(@svc.unexport(obj)).to be_equal(obj)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "returns the unexported leaf object, if specified by its path" do
|
|
78
|
+
obj = DBus::Object.new "/org/ruby/Foo"
|
|
79
|
+
@svc.export obj
|
|
80
|
+
expect(@svc.unexport(obj.path)).to be_equal(obj)
|
|
81
|
+
|
|
82
|
+
obj = DBus::Object.new "/org/ruby/Foo"
|
|
83
|
+
@svc.export obj
|
|
84
|
+
expect(@svc.unexport(DBus::ObjectPath.new(obj.path))).to be_equal(obj)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "returns false if the object was never exported" do
|
|
88
|
+
obj = DBus::Object.new "/org/ruby/Foo"
|
|
89
|
+
expect(@svc.unexport(obj)).to be false
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "raises false if the path has no node" do
|
|
93
|
+
obj = DBus::Object.new "/org/ruby/Foo"
|
|
94
|
+
@svc.export obj
|
|
95
|
+
expect { @svc.unexport("/org/ruby/NotFoo") }.to raise_error(ArgumentError)
|
|
96
|
+
@svc.unexport obj
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "raises false if the path has no object" do
|
|
100
|
+
obj = DBus::Object.new "/org/ruby/Foo"
|
|
101
|
+
@svc.export obj
|
|
102
|
+
expect { @svc.unexport("/org/ruby") }.to raise_error(ArgumentError)
|
|
103
|
+
@svc.unexport obj
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "raises when argument is not usable" do
|
|
107
|
+
expect { @svc.unexport(:foo) }.to raise_error(ArgumentError)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "/child_of_root" do
|
|
111
|
+
it "returns the unexported object" do
|
|
112
|
+
obj = DBus::Object.new "/child_of_root"
|
|
113
|
+
@svc.export obj
|
|
114
|
+
expect(@svc.unexport(obj)).to be_equal(obj)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
context "/ (root)" do
|
|
119
|
+
it "returns the unexported object" do
|
|
120
|
+
obj = DBus::Object.new "/"
|
|
121
|
+
@svc.export obj
|
|
122
|
+
expect(@svc.unexport(obj)).to be_equal(obj)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context "not a leaf object" do
|
|
127
|
+
it "maintains objects on child paths" do
|
|
128
|
+
obj = DBus::Object.new "/org/ruby"
|
|
129
|
+
@svc.export obj
|
|
130
|
+
obj2 = DBus::Object.new "/org/ruby/Foo"
|
|
131
|
+
@svc.export obj2
|
|
132
|
+
|
|
133
|
+
@svc.unexport(obj)
|
|
134
|
+
expect(@svc.object("/org/ruby/Foo")).to be_a DBus::Object
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
data/spec/object_spec.rb
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
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
|
+
|
|
65
|
+
it "fails when the signature is invalid" do
|
|
66
|
+
expect do
|
|
67
|
+
ObjectTest.instance_exec do
|
|
68
|
+
dbus_interface "org.ruby.ServerTest" do
|
|
69
|
+
dbus_reader :foo2, "!"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end.to raise_error(DBus::Type::SignatureException)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe ".dbus_reader, when paired with attr_accessor" do
|
|
77
|
+
describe "the declared assignment method" do
|
|
78
|
+
it "emits PropertyChanged" do
|
|
79
|
+
obj = ObjectTest.new("/test")
|
|
80
|
+
expect(obj).to receive(:PropertiesChanged).with(
|
|
81
|
+
"org.ruby.ServerTest",
|
|
82
|
+
{},
|
|
83
|
+
["ReadOnlyForDbus"]
|
|
84
|
+
)
|
|
85
|
+
obj.read_only_for_dbus = "myvalue"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe ".dbus_writer" do
|
|
91
|
+
it "can only be used within a dbus_interface" do
|
|
92
|
+
expect do
|
|
93
|
+
ObjectTest.instance_exec do
|
|
94
|
+
dbus_writer :foo, DBus::Type::STRING
|
|
95
|
+
end
|
|
96
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe ".dbus_watcher" do
|
|
101
|
+
it "can only be used within a dbus_interface" do
|
|
102
|
+
expect do
|
|
103
|
+
ObjectTest.instance_exec do
|
|
104
|
+
dbus_watcher :foo
|
|
105
|
+
end
|
|
106
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe ".dbus_method" do
|
|
111
|
+
it "can only be used within a dbus_interface" do
|
|
112
|
+
expect do
|
|
113
|
+
ObjectTest.instance_exec do
|
|
114
|
+
dbus_method :foo do
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe ".dbus_signal" do
|
|
122
|
+
it "can only be used within a dbus_interface" do
|
|
123
|
+
expect do
|
|
124
|
+
ObjectTest.instance_exec do
|
|
125
|
+
dbus_signal :signal_without_interface
|
|
126
|
+
end
|
|
127
|
+
end.to raise_error(DBus::Object::UndefinedInterface)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "cannot be named with a bang" do
|
|
131
|
+
expect do
|
|
132
|
+
ObjectTest.instance_exec do
|
|
133
|
+
dbus_interface "org.ruby.ServerTest" do
|
|
134
|
+
# a valid Ruby symbol but an invalid DBus name; Ticket#38
|
|
135
|
+
dbus_signal :signal_with_a_bang!
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end.to raise_error(DBus::InvalidMethodName)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe ".emits_changed_signal" do
|
|
143
|
+
it "raises UndefinedInterface when so" do
|
|
144
|
+
expect { ObjectTest.emits_changed_signal = false }
|
|
145
|
+
.to raise_error DBus::Object::UndefinedInterface
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "assigns to the current interface" do
|
|
149
|
+
ObjectTest.instance_exec do
|
|
150
|
+
dbus_interface "org.ruby.Interface" do
|
|
151
|
+
self.emits_changed_signal = false
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
ecs = ObjectTest.intfs["org.ruby.Interface"].emits_changed_signal
|
|
155
|
+
expect(ecs).to eq false
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "only can be assigned once" do
|
|
159
|
+
expect do
|
|
160
|
+
Class.new(DBus::Object) do
|
|
161
|
+
dbus_interface "org.ruby.Interface" do
|
|
162
|
+
self.emits_changed_signal = false
|
|
163
|
+
self.emits_changed_signal = :invalidates
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end.to raise_error(RuntimeError, /assigned more than once/)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# coverage obsession
|
|
171
|
+
describe "#dispatch" do
|
|
172
|
+
it "survives being called with a non-METHOD_CALL, doing nothing" do
|
|
173
|
+
obj = ObjectTest.new("/test")
|
|
174
|
+
msg = DBus::MethodReturnMessage.new
|
|
175
|
+
expect { obj.dispatch(msg) }.to_not raise_error
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
describe "#emit" do
|
|
180
|
+
context "before the object has been exported" do
|
|
181
|
+
it "raises an explanatory error" do
|
|
182
|
+
obj = ObjectTest.new("/test")
|
|
183
|
+
|
|
184
|
+
intf = DBus::Interface.new("org.example.Test")
|
|
185
|
+
signal = DBus::Signal.new("Ring")
|
|
186
|
+
expect { obj.emit(intf, signal) }
|
|
187
|
+
.to raise_error(
|
|
188
|
+
RuntimeError,
|
|
189
|
+
%r{Cannot emit signal org.example.Test.Ring before /test is exported}
|
|
190
|
+
)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
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
|