ruby-dbus 0.17.0 → 0.18.0.beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/NEWS.md +38 -0
- data/README.md +1 -1
- data/Rakefile +3 -11
- data/VERSION +1 -1
- data/doc/Reference.md +10 -3
- data/examples/doc/_extract_examples +2 -0
- data/examples/gdbus/gdbus +11 -5
- 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 +1 -0
- 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 +12 -7
- data/lib/dbus/bus.rb +114 -70
- data/lib/dbus/bus_name.rb +12 -8
- data/lib/dbus/data.rb +744 -0
- data/lib/dbus/error.rb +4 -2
- data/lib/dbus/introspect.rb +30 -18
- data/lib/dbus/logger.rb +3 -1
- data/lib/dbus/marshall.rb +229 -293
- data/lib/dbus/matchrule.rb +16 -16
- data/lib/dbus/message.rb +44 -37
- data/lib/dbus/message_queue.rb +10 -5
- data/lib/dbus/object.rb +36 -15
- data/lib/dbus/object_path.rb +11 -6
- data/lib/dbus/proxy_object.rb +18 -4
- data/lib/dbus/proxy_object_factory.rb +11 -7
- data/lib/dbus/proxy_object_interface.rb +26 -22
- data/lib/dbus/raw_message.rb +91 -0
- data/lib/dbus/type.rb +164 -80
- data/lib/dbus/xml.rb +28 -17
- data/lib/dbus.rb +13 -7
- data/ruby-dbus.gemspec +4 -2
- 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 +1639 -0
- data/spec/data_spec.rb +353 -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 +2 -0
- data/spec/node_spec.rb +23 -0
- data/spec/object_path_spec.rb +3 -0
- data/spec/packet_marshaller_spec.rb +34 -0
- data/spec/packet_unmarshaller_spec.rb +262 -0
- data/spec/property_spec.rb +60 -2
- 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 +37 -4
- data/spec/session_bus_spec.rb +3 -1
- data/spec/session_bus_spec_manual.rb +2 -0
- data/spec/signal_spec.rb +2 -0
- data/spec/spec_helper.rb +19 -3
- data/spec/thread_safety_spec.rb +2 -0
- data/spec/type_spec.rb +69 -6
- data/spec/value_spec.rb +16 -1
- data/spec/variant_spec.rb +4 -2
- data/spec/zzz_quit_spec.rb +16 -0
- metadata +16 -7
@@ -0,0 +1,262 @@
|
|
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
|
+
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
|
59
|
+
|
60
|
+
expect(remaining_buffer(subject)).to be_empty
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# this is necessary because we do an early switch on the signature
|
67
|
+
RSpec.shared_examples "reports empty data" do
|
68
|
+
it "reports empty data" do
|
69
|
+
[:big, :little].each do |endianness|
|
70
|
+
subject = described_class.new("", endianness)
|
71
|
+
expect { subject.unmarshall(signature) }.to raise_error(DBus::IncompleteBufferException)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe DBus::PacketUnmarshaller do
|
77
|
+
context "marshall.yaml" do
|
78
|
+
marshall_yaml.each do |test|
|
79
|
+
t = OpenStruct.new(test)
|
80
|
+
signature = t.sig
|
81
|
+
buffer = buffer_from_yaml(t.buf)
|
82
|
+
endianness = t.end.to_sym
|
83
|
+
|
84
|
+
# successful parse
|
85
|
+
if !t.val.nil?
|
86
|
+
expected = t.val
|
87
|
+
|
88
|
+
it "parses a '#{signature}' to get #{t.val.inspect} (plain)" do
|
89
|
+
subject = described_class.new(buffer, endianness)
|
90
|
+
results = subject.unmarshall(signature, mode: :plain)
|
91
|
+
# unmarshall works on multiple signatures but we use one
|
92
|
+
expect(results).to be_an(Array)
|
93
|
+
expect(results.size).to eq(1)
|
94
|
+
result = results.first
|
95
|
+
|
96
|
+
expect(result).to eq(expected)
|
97
|
+
expect(remaining_buffer(subject)).to be_empty
|
98
|
+
end
|
99
|
+
|
100
|
+
it "parses a '#{t.sig}' to get #{t.val.inspect} (exact)" do
|
101
|
+
subject = described_class.new(buffer, endianness)
|
102
|
+
results = subject.unmarshall(signature, mode: :exact)
|
103
|
+
# unmarshall works on multiple signatures but we use one
|
104
|
+
expect(results).to be_an(Array)
|
105
|
+
expect(results.size).to eq(1)
|
106
|
+
result = results.first
|
107
|
+
|
108
|
+
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
|
117
|
+
|
118
|
+
expect(remaining_buffer(subject)).to be_empty
|
119
|
+
end
|
120
|
+
elsif t.exc
|
121
|
+
next if t.unmarshall == false
|
122
|
+
|
123
|
+
exc_class = DBus.const_get(t.exc)
|
124
|
+
msg_re = Regexp.new(Regexp.escape(t.msg))
|
125
|
+
|
126
|
+
# TODO: InvalidPacketException is never rescued.
|
127
|
+
# The other end is sending invalid data. Can we do better than crashing?
|
128
|
+
# When we can test with peer connections, try it out.
|
129
|
+
it "parses a '#{signature}' to report a #{t.exc}" do
|
130
|
+
subject = described_class.new(buffer, endianness)
|
131
|
+
expect { subject.unmarshall(signature, mode: :plain) }.to raise_error(exc_class, msg_re)
|
132
|
+
|
133
|
+
subject = described_class.new(buffer, endianness)
|
134
|
+
expect { subject.unmarshall(signature, mode: :exact) }.to raise_error(exc_class, msg_re)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "BYTEs" do
|
141
|
+
let(:signature) { "y" }
|
142
|
+
include_examples "reports empty data"
|
143
|
+
end
|
144
|
+
|
145
|
+
context "BOOLEANs" do
|
146
|
+
let(:signature) { "b" }
|
147
|
+
include_examples "reports empty data"
|
148
|
+
end
|
149
|
+
|
150
|
+
context "INT16s" do
|
151
|
+
let(:signature) { "n" }
|
152
|
+
include_examples "reports empty data"
|
153
|
+
end
|
154
|
+
|
155
|
+
context "UINT16s" do
|
156
|
+
let(:signature) { "q" }
|
157
|
+
include_examples "reports empty data"
|
158
|
+
end
|
159
|
+
|
160
|
+
context "INT32s" do
|
161
|
+
let(:signature) { "i" }
|
162
|
+
include_examples "reports empty data"
|
163
|
+
end
|
164
|
+
|
165
|
+
context "UINT32s" do
|
166
|
+
let(:signature) { "u" }
|
167
|
+
include_examples "reports empty data"
|
168
|
+
end
|
169
|
+
|
170
|
+
context "UNIX_FDs" do
|
171
|
+
let(:signature) { "h" }
|
172
|
+
include_examples "reports empty data"
|
173
|
+
end
|
174
|
+
|
175
|
+
context "INT64s" do
|
176
|
+
let(:signature) { "x" }
|
177
|
+
include_examples "reports empty data"
|
178
|
+
end
|
179
|
+
|
180
|
+
context "UINT64s" do
|
181
|
+
let(:signature) { "t" }
|
182
|
+
include_examples "reports empty data"
|
183
|
+
end
|
184
|
+
|
185
|
+
context "DOUBLEs" do
|
186
|
+
let(:signature) { "d" }
|
187
|
+
# See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
|
188
|
+
# for binary representations
|
189
|
+
# TODO: figure out IEEE754 comparisons
|
190
|
+
good = [
|
191
|
+
# But == cant distinguish -0.0
|
192
|
+
["\x00\x00\x00\x00\x00\x00\x00\x80", :little, -0.0],
|
193
|
+
# But NaN == NaN is false!
|
194
|
+
# ["\xff\xff\xff\xff\xff\xff\xff\xff", :little, Float::NAN],
|
195
|
+
["\x80\x00\x00\x00\x00\x00\x00\x00", :big, -0.0]
|
196
|
+
# ["\xff\xff\xff\xff\xff\xff\xff\xff", :big, Float::NAN]
|
197
|
+
]
|
198
|
+
include_examples "parses good data", good
|
199
|
+
include_examples "reports empty data"
|
200
|
+
end
|
201
|
+
|
202
|
+
context "STRINGs" do
|
203
|
+
let(:signature) { "s" }
|
204
|
+
include_examples "reports empty data"
|
205
|
+
end
|
206
|
+
|
207
|
+
context "OBJECT_PATHs" do
|
208
|
+
let(:signature) { "o" }
|
209
|
+
include_examples "reports empty data"
|
210
|
+
end
|
211
|
+
|
212
|
+
context "SIGNATUREs" do
|
213
|
+
let(:signature) { "g" }
|
214
|
+
include_examples "reports empty data"
|
215
|
+
end
|
216
|
+
|
217
|
+
context "ARRAYs" do
|
218
|
+
context "of BYTEs" do
|
219
|
+
let(:signature) { "ay" }
|
220
|
+
include_examples "reports empty data"
|
221
|
+
end
|
222
|
+
|
223
|
+
context "of UINT64s" do
|
224
|
+
let(:signature) { "at" }
|
225
|
+
include_examples "reports empty data"
|
226
|
+
end
|
227
|
+
|
228
|
+
context "of STRUCT of 2 UINT16s" do
|
229
|
+
let(:signature) { "a(qq)" }
|
230
|
+
include_examples "reports empty data"
|
231
|
+
end
|
232
|
+
|
233
|
+
context "of DICT_ENTRIES" do
|
234
|
+
let(:signature) { "a{yq}" }
|
235
|
+
include_examples "reports empty data"
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "STRUCTs" do
|
240
|
+
# TODO: this is invalid but does not raise
|
241
|
+
context "(generic 'r' struct)" do
|
242
|
+
let(:signature) { "r" }
|
243
|
+
end
|
244
|
+
|
245
|
+
context "of two shorts" do
|
246
|
+
let(:signature) { "(qq)" }
|
247
|
+
include_examples "reports empty data"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# makes sense here? or in array? remember invalid sigs are rejected elsewhere
|
252
|
+
context "DICT_ENTRYs" do
|
253
|
+
context "(generic 'e' dict_entry)" do
|
254
|
+
let(:signature) { "e" }
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context "VARIANTs" do
|
259
|
+
let(:signature) { "v" }
|
260
|
+
include_examples "reports empty data"
|
261
|
+
end
|
262
|
+
end
|
data/spec/property_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
|
|
@@ -50,7 +52,7 @@ describe "PropertyTest" do
|
|
50
52
|
|
51
53
|
it "tests get all" do
|
52
54
|
all = @iface.all_properties
|
53
|
-
expect(all.keys.sort).to eq(["ReadMe", "ReadOrWriteMe"])
|
55
|
+
expect(all.keys.sort).to eq(["MyArray", "MyDict", "MyStruct", "MyVariant", "ReadMe", "ReadOrWriteMe"])
|
54
56
|
end
|
55
57
|
|
56
58
|
it "tests get all on a V1 object" do
|
@@ -58,7 +60,7 @@ describe "PropertyTest" do
|
|
58
60
|
iface = obj["org.ruby.SampleInterface"]
|
59
61
|
|
60
62
|
all = iface.all_properties
|
61
|
-
expect(all.keys.sort).to eq(["ReadMe", "ReadOrWriteMe"])
|
63
|
+
expect(all.keys.sort).to eq(["MyArray", "MyDict", "MyStruct", "MyVariant", "ReadMe", "ReadOrWriteMe"])
|
62
64
|
end
|
63
65
|
|
64
66
|
it "tests unknown property reading" do
|
@@ -114,4 +116,60 @@ describe "PropertyTest" do
|
|
114
116
|
|
115
117
|
expect(received["ReadOrWriteMe"]).to eq("VALUE")
|
116
118
|
end
|
119
|
+
|
120
|
+
context "a struct-typed property" do
|
121
|
+
it "gets read as a struct, not an array (#97)" do
|
122
|
+
struct = @iface["MyStruct"]
|
123
|
+
expect(struct).to be_frozen
|
124
|
+
end
|
125
|
+
|
126
|
+
it "Get returns the correctly typed value (check with dbus-send)" do
|
127
|
+
# As big as the DBus::Data branch is,
|
128
|
+
# it still does not handle the :exact mode on the client/proxy side.
|
129
|
+
# So we resort to parsing dbus-send output.
|
130
|
+
cmd = "dbus-send --print-reply " \
|
131
|
+
"--dest=org.ruby.service " \
|
132
|
+
"/org/ruby/MyInstance " \
|
133
|
+
"org.freedesktop.DBus.Properties.Get " \
|
134
|
+
"string:org.ruby.SampleInterface " \
|
135
|
+
"string:MyStruct"
|
136
|
+
reply = `#{cmd}`
|
137
|
+
expect(reply).to match(/variant\s+struct {\s+string "three"\s+string "strings"\s+string "in a struct"\s+}/)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "GetAll returns the correctly typed value (check with dbus-send)" do
|
141
|
+
cmd = "dbus-send --print-reply " \
|
142
|
+
"--dest=org.ruby.service " \
|
143
|
+
"/org/ruby/MyInstance " \
|
144
|
+
"org.freedesktop.DBus.Properties.GetAll " \
|
145
|
+
"string:org.ruby.SampleInterface "
|
146
|
+
reply = `#{cmd}`
|
147
|
+
expect(reply).to match(/variant\s+struct {\s+string "three"\s+string "strings"\s+string "in a struct"\s+}/)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "an array-typed property" do
|
152
|
+
it "gets read as an array" do
|
153
|
+
val = @iface["MyArray"]
|
154
|
+
expect(val).to eq([42, 43])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "an dict-typed property" do
|
159
|
+
it "gets read as a hash" do
|
160
|
+
val = @iface["MyDict"]
|
161
|
+
expect(val).to eq({
|
162
|
+
"one" => 1,
|
163
|
+
"two" => "dva",
|
164
|
+
"three" => [3, 3, 3]
|
165
|
+
})
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "a variant-typed property" do
|
170
|
+
it "gets read at all" do
|
171
|
+
val = @iface["MyVariant"]
|
172
|
+
expect(val).to eq([42, 43])
|
173
|
+
end
|
174
|
+
end
|
117
175
|
end
|
data/spec/proxy_object_spec.rb
CHANGED
data/spec/server_spec.rb
CHANGED
data/spec/service_newapi.rb
CHANGED
@@ -1,25 +1,42 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
2
|
+
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require_relative "spec_helper"
|
5
5
|
SimpleCov.command_name "Service Tests" if Object.const_defined? "SimpleCov"
|
6
6
|
# find the library without external help
|
7
|
-
$LOAD_PATH.unshift File.expand_path("
|
7
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
8
8
|
|
9
9
|
require "dbus"
|
10
10
|
|
11
|
-
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
|
11
|
+
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
|
12
12
|
|
13
13
|
class Test < DBus::Object
|
14
|
-
|
14
|
+
Point2D = Struct.new(:x, :y)
|
15
|
+
|
16
|
+
attr_writer :main_loop
|
17
|
+
|
18
|
+
INTERFACE = "org.ruby.SampleInterface"
|
15
19
|
def initialize(path)
|
16
20
|
super path
|
17
21
|
@read_me = "READ ME"
|
18
22
|
@read_or_write_me = "READ OR WRITE ME"
|
23
|
+
@my_struct = ["three", "strings", "in a struct"].freeze
|
24
|
+
@my_array = [42, 43]
|
25
|
+
@my_dict = {
|
26
|
+
"one" => 1,
|
27
|
+
"two" => "dva",
|
28
|
+
"three" => [3, 3, 3]
|
29
|
+
}
|
30
|
+
@my_variant = @my_array.dup
|
31
|
+
@main_loop = nil
|
19
32
|
end
|
20
33
|
|
21
34
|
# Create an interface aggregating all upcoming dbus_method defines.
|
22
35
|
dbus_interface INTERFACE do
|
36
|
+
dbus_method :quit, "" do
|
37
|
+
@main_loop&.quit
|
38
|
+
end
|
39
|
+
|
23
40
|
dbus_method :hello, "in name:s, in name2:s" do |name, name2|
|
24
41
|
puts "hello(#{name}, #{name2})"
|
25
42
|
end
|
@@ -60,6 +77,16 @@ class Test < DBus::Object
|
|
60
77
|
[bytes]
|
61
78
|
end
|
62
79
|
|
80
|
+
dbus_method :Coordinates, "out coords:(dd)" do
|
81
|
+
coords = [3.0, 4.0].freeze
|
82
|
+
[coords]
|
83
|
+
end
|
84
|
+
|
85
|
+
dbus_method :Coordinates2, "out coords:(dd)" do
|
86
|
+
coords = Point2D.new(5.0, 12.0)
|
87
|
+
[coords]
|
88
|
+
end
|
89
|
+
|
63
90
|
# Properties:
|
64
91
|
# ReadMe:string, returns "READ ME" at first, then what WriteMe received
|
65
92
|
# WriteMe:string
|
@@ -79,6 +106,11 @@ class Test < DBus::Object
|
|
79
106
|
raise "Something failed"
|
80
107
|
end
|
81
108
|
dbus_reader :explosive, "s"
|
109
|
+
|
110
|
+
dbus_attr_reader :my_struct, "(sss)"
|
111
|
+
dbus_attr_reader :my_array, "aq"
|
112
|
+
dbus_attr_reader :my_dict, "a{sv}"
|
113
|
+
dbus_attr_reader :my_variant, "v"
|
82
114
|
end
|
83
115
|
|
84
116
|
# closing and reopening the same interface
|
@@ -178,6 +210,7 @@ end
|
|
178
210
|
puts "listening, with ruby-#{RUBY_VERSION}"
|
179
211
|
main = DBus::Main.new
|
180
212
|
main << bus
|
213
|
+
myobj.main_loop = main
|
181
214
|
begin
|
182
215
|
main.run
|
183
216
|
rescue SystemCallError
|
data/spec/session_bus_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
|
|
@@ -23,7 +25,7 @@ describe DBus::ASessionBus do
|
|
23
25
|
|
24
26
|
before do
|
25
27
|
# mocks of files for address_from_file method
|
26
|
-
machine_id_path = File.expand_path("/etc/machine-id",
|
28
|
+
machine_id_path = File.expand_path("/etc/machine-id", __dir__)
|
27
29
|
expect(Dir).to receive(:[]).with(any_args) { [machine_id_path] }
|
28
30
|
expect(File).to receive(:read).with(machine_id_path) { "baz" }
|
29
31
|
expect(File).to receive(:exist?).with(session_bus_file_path) { true }
|
data/spec/signal_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
coverage = if ENV["COVERAGE"]
|
2
4
|
ENV["COVERAGE"] == "true"
|
3
5
|
else
|
@@ -7,12 +9,14 @@ coverage = if ENV["COVERAGE"]
|
|
7
9
|
|
8
10
|
if coverage
|
9
11
|
require "simplecov"
|
10
|
-
SimpleCov.root File.expand_path("
|
12
|
+
SimpleCov.root File.expand_path("..", __dir__)
|
11
13
|
|
12
14
|
# do not cover specs
|
13
15
|
SimpleCov.add_filter "_spec.rb"
|
14
16
|
# do not cover the activesupport helpers
|
15
17
|
SimpleCov.add_filter "/core_ext/"
|
18
|
+
# measure all if/else branches on a line
|
19
|
+
SimpleCov.enable_coverage :branch
|
16
20
|
|
17
21
|
SimpleCov.start
|
18
22
|
|
@@ -34,7 +38,7 @@ if coverage
|
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
37
|
-
$LOAD_PATH.unshift File.expand_path("
|
41
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
38
42
|
|
39
43
|
if Object.const_defined? "RSpec"
|
40
44
|
# http://betterspecs.org/#expect
|
@@ -48,7 +52,7 @@ end
|
|
48
52
|
require "tempfile"
|
49
53
|
require "timeout"
|
50
54
|
|
51
|
-
TOPDIR = File.expand_path("
|
55
|
+
TOPDIR = File.expand_path("..", __dir__)
|
52
56
|
|
53
57
|
# path of config file for a private bus
|
54
58
|
def config_file_path
|
@@ -116,3 +120,15 @@ def with_service_by_activation(&block)
|
|
116
120
|
|
117
121
|
system "pkill -f #{exec}"
|
118
122
|
end
|
123
|
+
|
124
|
+
# Make a binary string from readable YAML pieces; see data/marshall.yaml
|
125
|
+
def buffer_from_yaml(parts)
|
126
|
+
strings = parts.flatten.map do |part|
|
127
|
+
if part.is_a? Integer
|
128
|
+
part.chr
|
129
|
+
else
|
130
|
+
part
|
131
|
+
end
|
132
|
+
end
|
133
|
+
strings.join.force_encoding(Encoding::BINARY)
|
134
|
+
end
|
data/spec/thread_safety_spec.rb
CHANGED
data/spec/type_spec.rb
CHANGED
@@ -1,18 +1,81 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require_relative "spec_helper"
|
3
5
|
require "dbus"
|
4
6
|
|
5
7
|
describe DBus do
|
6
8
|
describe ".type" do
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
good = [
|
10
|
+
"i",
|
11
|
+
"ai",
|
12
|
+
"a(ii)",
|
13
|
+
"aai"
|
14
|
+
]
|
15
|
+
|
16
|
+
context "valid single types" do
|
17
|
+
good.each do |s|
|
18
|
+
it "#{s.inspect} is parsed" do
|
19
|
+
expect(DBus.type(s).to_s).to eq(s)
|
20
|
+
end
|
10
21
|
end
|
11
22
|
end
|
12
23
|
|
13
|
-
|
14
|
-
|
15
|
-
|
24
|
+
bad = [
|
25
|
+
["\x00", "Unknown type code"],
|
26
|
+
["!", "Unknown type code"],
|
27
|
+
|
28
|
+
# ARRAY related
|
29
|
+
["a", "Empty ARRAY"],
|
30
|
+
["aa", "Empty ARRAY"],
|
31
|
+
|
32
|
+
# STRUCT related
|
33
|
+
["r", "Abstract STRUCT"],
|
34
|
+
["()", "Empty STRUCT"],
|
35
|
+
["(ii", "STRUCT not closed"],
|
36
|
+
["a{i)", "STRUCT unexpectedly closed"],
|
37
|
+
|
38
|
+
# TODO: deep nesting arrays, structs, combined
|
39
|
+
|
40
|
+
# DICT_ENTRY related
|
41
|
+
["e", "Abstract DICT_ENTRY"],
|
42
|
+
["a{}", "DICT_ENTRY must have 2 subtypes, found 0"],
|
43
|
+
["a{s}", "DICT_ENTRY must have 2 subtypes, found 1"],
|
44
|
+
["a{sss}", "DICT_ENTRY must have 2 subtypes, found 3"],
|
45
|
+
["a{vs}", "DICT_ENTRY key must be basic (non-container)"],
|
46
|
+
["{sv}", "DICT_ENTRY not an immediate child of an ARRAY"],
|
47
|
+
["a({sv})", "DICT_ENTRY not an immediate child of an ARRAY"],
|
48
|
+
["a{sv", "DICT_ENTRY not closed"],
|
49
|
+
["}", "DICT_ENTRY unexpectedly closed"],
|
50
|
+
|
51
|
+
# Too long
|
52
|
+
["(#{"y" * 254})", "longer than 255"],
|
53
|
+
|
54
|
+
# not Single Complete Types
|
55
|
+
["", "expecting a Single Complete Type"],
|
56
|
+
["ii", "more than a Single Complete Type"]
|
57
|
+
]
|
58
|
+
context "invalid single types" do
|
59
|
+
bad.each.each do |s, msg|
|
60
|
+
it "#{s.inspect} raises an exception mentioning: #{msg}" do
|
61
|
+
rx = Regexp.new(Regexp.quote(msg))
|
62
|
+
expect { DBus.type(s) }.to raise_error(DBus::Type::SignatureException, rx)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe ".types" do
|
69
|
+
good = [
|
70
|
+
"",
|
71
|
+
"ii"
|
72
|
+
]
|
73
|
+
|
74
|
+
context "valid signatures" do
|
75
|
+
good.each do |s|
|
76
|
+
it "#{s.inspect} is parsed" do
|
77
|
+
expect(DBus.types(s).map(&:to_s).join).to eq(s)
|
78
|
+
end
|
16
79
|
end
|
17
80
|
end
|
18
81
|
end
|
data/spec/value_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
|
-
#
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
3
4
|
require_relative "spec_helper"
|
4
5
|
require "dbus"
|
5
6
|
|
@@ -91,4 +92,18 @@ describe "ValueTest" do
|
|
91
92
|
it "aligns short integers correctly" do
|
92
93
|
expect(@obj.i16_plus(10, -30)[0]).to eq(-20)
|
93
94
|
end
|
95
|
+
|
96
|
+
context "structs" do
|
97
|
+
it "they are returned as FROZEN arrays" do
|
98
|
+
struct = @obj.Coordinates[0]
|
99
|
+
expect(struct).to be_an(Array)
|
100
|
+
expect(struct).to be_frozen
|
101
|
+
end
|
102
|
+
|
103
|
+
it "they are returned also from structs" do
|
104
|
+
struct = @obj.Coordinates2[0]
|
105
|
+
expect(struct).to be_an(Array)
|
106
|
+
expect(struct).to be_frozen
|
107
|
+
end
|
108
|
+
end
|
94
109
|
end
|
data/spec/variant_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# Test marshalling variants according to ruby types
|
3
5
|
require_relative "spec_helper"
|
4
6
|
require "dbus"
|
@@ -9,8 +11,8 @@ describe "VariantTest" do
|
|
9
11
|
@svc = @bus.service("org.ruby.service")
|
10
12
|
end
|
11
13
|
|
12
|
-
def make_variant(
|
13
|
-
DBus::PacketMarshaller.make_variant(
|
14
|
+
def make_variant(val)
|
15
|
+
DBus::PacketMarshaller.make_variant(val)
|
14
16
|
end
|
15
17
|
|
16
18
|
it "tests make variant scalar" do
|