rbus 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +8 -2
- data/Manifest.txt +1 -0
- data/TUTORIAL.txt +66 -14
- data/bin/rbus-send +10 -64
- data/examples/hal_device_info.rb +3 -4
- data/lib/rbus/bus/bus.rb +5 -7
- data/lib/rbus/bus/proxy.rb +104 -12
- data/lib/rbus/etc/blankslate.rb +8 -0
- data/lib/rbus/etc/version.rb +1 -1
- data/lib/rbus/mainloop/mainloop.rb +7 -6
- data/spec/bus_spec.rb +11 -14
- data/spec/mainloop_spec.rb +6 -3
- data/spec/message_spec.rb +1 -1
- data/spec/proxy_spec.rb +70 -0
- metadata +3 -2
data/CHANGELOG.txt
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
=CHANGELOG
|
2
2
|
|
3
|
-
|
3
|
+
R-Bus 0.1.1 2007-03-30
|
4
|
+
* Signature guessing code
|
5
|
+
* Support for dbus-send style arguments
|
6
|
+
* Tutorial updates
|
7
|
+
* Bugfixes and more tests
|
8
|
+
|
9
|
+
R-Bus 0.1.0 2007-03-28
|
4
10
|
* Released as Rubygem
|
5
11
|
* Added rbus-send application
|
6
12
|
* Bugfixes and other updates
|
7
13
|
|
8
|
-
|
14
|
+
R-Bus 0.0.1 2007-03-26
|
9
15
|
* Initial release (source only)
|
data/Manifest.txt
CHANGED
data/TUTORIAL.txt
CHANGED
@@ -101,17 +101,64 @@ Some examples of method calls:
|
|
101
101
|
|
102
102
|
== Signatures, introspection and data types
|
103
103
|
|
104
|
-
D-Bus
|
105
|
-
{
|
106
|
-
that can be used to send and receive data between applications.
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
104
|
+
D-Bus defines a number of standard
|
105
|
+
{data types}[http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures]
|
106
|
+
that can be used to send and receive data between applications. Each method and
|
107
|
+
signal has a signature that shows how many arguments and of what types it
|
108
|
+
expects and/or returns. A few examples of signatures:
|
109
|
+
|
110
|
+
[+s+] a String
|
111
|
+
[+ui+] Uint32, Int32
|
112
|
+
[+as+] Array of Strings
|
113
|
+
[<tt>a{sas}</tt>] Dict, or Hash in Ruby, with String keys and Arrays of Strings as values.
|
114
|
+
|
115
|
+
R-Bus is able to use Rubys standard types without any conversion for the most
|
116
|
+
part, as long as there is a known signature available for the conversion. This
|
117
|
+
signature can be obtained in a number of ways, and the library tries really
|
118
|
+
hard to find one:
|
119
|
+
|
120
|
+
When a new Proxy object is created, R-Bus will ask the remote application for a
|
121
|
+
list of methods and signatures via the standard method +Introspect+. If the
|
122
|
+
application provides such a list (and most do), everything should just work. :)
|
123
|
+
|
124
|
+
If the introspection fails, the library tries to guess the signature from the
|
125
|
+
arguments the method was called with. It will handle most types except integers
|
126
|
+
automatically, as long as the structures aren't too complex. Currently, these
|
127
|
+
Ruby classes are properly handled:
|
128
|
+
|
129
|
+
* String - D-Bus string
|
130
|
+
* Symbol - D-Bus string
|
131
|
+
* TrueClass and FalseClass - D-Bus boolean
|
132
|
+
* Float - D-Bus double
|
133
|
+
* Hash - D-Bus array of dicts
|
134
|
+
* can not be empty, needs at least one key/value pair
|
135
|
+
* Array
|
136
|
+
* D-Bus array if all values have the same signature (symbol and string is
|
137
|
+
considered to be the same)
|
138
|
+
* D-Bus struct if there are mixed values
|
139
|
+
* can't handle array of containers
|
140
|
+
|
141
|
+
So, a call like:
|
142
|
+
|
143
|
+
object.Method({:key => ['value'], 'key2' => ['value']})
|
144
|
+
|
145
|
+
will result in the signature <tt>a{sas}</tt>. And so on.
|
146
|
+
|
147
|
+
Also, you can manually give any arguments in the same form as <em>rbus-send</em>
|
148
|
+
(and <em>dbus-send</em>) accepts. This is the value, as a string, prefixed with
|
149
|
+
the name of the type and a colon:
|
150
|
+
|
151
|
+
string:'some string'
|
152
|
+
uint32:42
|
153
|
+
int16:-25
|
154
|
+
array:string:'foo','bar'
|
155
|
+
dict:string:uint32:'foo',32,'bar',64
|
156
|
+
|
157
|
+
See the section on rbus-send at the bottom of this document for the
|
158
|
+
specification of the format and some examples.
|
159
|
+
|
160
|
+
If all this fails, finally you can add the method manually with
|
161
|
+
<tt>method!</tt>:
|
115
162
|
|
116
163
|
obj.method!(:MethodName, 'as')
|
117
164
|
|
@@ -237,13 +284,18 @@ currently missing.</em>
|
|
237
284
|
=== rbus-send
|
238
285
|
|
239
286
|
R-Bus comes with its own variant of <em>dbus-send</em>, called
|
240
|
-
<em>{rbus-send}[link:files/bin/rbus-send.html]</em>, which should be pretty much
|
241
|
-
|
287
|
+
<em>{rbus-send}[link:files/bin/rbus-send.html]</em>, which should be pretty much
|
288
|
+
compatible, except for:
|
242
289
|
|
243
290
|
* There is no <tt>--reply-timeout</tt>. Trivial to fix in seconds, though
|
244
|
-
milli-seconds may not be.
|
291
|
+
milli-seconds may not be. Will be added.
|
245
292
|
* Currently dumps the any server answer in YAML[http://www.yaml.org/] instead of
|
246
293
|
the dbus-send format.
|
294
|
+
* Does not demand that an interface be specified, meaning you can call, as an
|
295
|
+
example, the method <tt>Introspect</tt> instead of the qualified
|
296
|
+
<tt>org.freedesktop.DBus.Introspectable.Introspect</tt>, as long as the
|
297
|
+
method is unique in the object. As the specification clearly allows this for
|
298
|
+
any client, I consider this a feature.
|
247
299
|
|
248
300
|
The invokation looks like this:
|
249
301
|
|
data/bin/rbus-send
CHANGED
@@ -49,55 +49,6 @@ require 'optparse'
|
|
49
49
|
require 'rbus'
|
50
50
|
require 'yaml'
|
51
51
|
|
52
|
-
def make_signature # :nodoc:
|
53
|
-
translation = {
|
54
|
-
'byte' => 'y',
|
55
|
-
'boolean' => 'b',
|
56
|
-
'int16' => 'n',
|
57
|
-
'uint16' => 'q',
|
58
|
-
'int32' => 'i',
|
59
|
-
'uint32' => 'u',
|
60
|
-
'int64' => 'x',
|
61
|
-
'uint64' => 't',
|
62
|
-
'double' => 'd',
|
63
|
-
'string' => 's',
|
64
|
-
'objpath' => 'o',
|
65
|
-
'signature' => 'g',
|
66
|
-
'variant' => 'v',
|
67
|
-
'array' => 'a',
|
68
|
-
'dict' => 'a{',
|
69
|
-
}
|
70
|
-
|
71
|
-
signature = ''
|
72
|
-
array = false
|
73
|
-
|
74
|
-
ARGV.map!{|a|
|
75
|
-
type, arg = a.split(':',2)
|
76
|
-
fail "Unknown type '#{type}'" unless translation.has_key?(type)
|
77
|
-
signature << translation[type]
|
78
|
-
case type
|
79
|
-
when 'dict'
|
80
|
-
key,value,arg = arg.split(':',3)
|
81
|
-
signature << translation[key]
|
82
|
-
signature << translation[value]
|
83
|
-
signature << '}'
|
84
|
-
arg.nil? ? {} : Hash[*arg.split(',')]
|
85
|
-
when 'array'
|
86
|
-
array = true
|
87
|
-
a = arg
|
88
|
-
redo
|
89
|
-
when 'variant'
|
90
|
-
a = arg
|
91
|
-
redo
|
92
|
-
else
|
93
|
-
rv = (array) ? arg.split(',') : arg
|
94
|
-
array = false
|
95
|
-
rv
|
96
|
-
end
|
97
|
-
}
|
98
|
-
signature
|
99
|
-
end
|
100
|
-
|
101
52
|
klass = RBus::Signal
|
102
53
|
destination = nil
|
103
54
|
bus = nil
|
@@ -113,7 +64,7 @@ opts = OptionParser.new do |opts|
|
|
113
64
|
}
|
114
65
|
|
115
66
|
opts.on('--print-reply',
|
116
|
-
'
|
67
|
+
'Wait for, and print reply.') {
|
117
68
|
print_reply = true
|
118
69
|
klass = RBus::MethodCall
|
119
70
|
}
|
@@ -122,7 +73,7 @@ opts = OptionParser.new do |opts|
|
|
122
73
|
bus = RBus.system_bus
|
123
74
|
}
|
124
75
|
|
125
|
-
opts.on('--session', 'Send to the session message bus. (
|
76
|
+
opts.on('--session', 'Send to the session message bus. (default.)') {
|
126
77
|
bus = RBus.session_bus
|
127
78
|
}
|
128
79
|
|
@@ -135,6 +86,10 @@ opts = OptionParser.new do |opts|
|
|
135
86
|
}
|
136
87
|
end
|
137
88
|
|
89
|
+
opts.version = RBus::VERSION::STRING
|
90
|
+
opts.summary_width = 18
|
91
|
+
opts.summary_indent = ""
|
92
|
+
|
138
93
|
opts.parse!
|
139
94
|
|
140
95
|
if ARGV.length < 2
|
@@ -146,20 +101,11 @@ object_path = ARGV.shift
|
|
146
101
|
member,interface = ARGV.shift.reverse.split('.',2).map{|s|s.reverse}
|
147
102
|
|
148
103
|
bus = RBus.session_bus if bus.nil?
|
149
|
-
|
150
|
-
|
151
|
-
m.destination = destination
|
152
|
-
m.object_path = object_path
|
153
|
-
m.interface = interface
|
154
|
-
m.member = member
|
155
|
-
m.signature = make_signature
|
156
|
-
m.arguments = ARGV
|
157
|
-
end
|
158
|
-
|
159
|
-
#puts YAML.dump(message);exit
|
104
|
+
object = bus.get_object(destination, object_path)
|
105
|
+
object.interface!(interface)
|
160
106
|
|
161
107
|
if print_reply
|
162
|
-
puts YAML.dump(
|
108
|
+
puts YAML.dump(object.__send__(member, *ARGV))
|
163
109
|
else
|
164
|
-
|
110
|
+
object.__send__(member, *ARGV){}
|
165
111
|
end
|
data/examples/hal_device_info.rb
CHANGED
@@ -26,6 +26,9 @@
|
|
26
26
|
# RBus Example:
|
27
27
|
# Get information about a random HAL device.
|
28
28
|
#
|
29
|
+
# At least in my version, HAL does not provide introspection, but
|
30
|
+
# the library now handles guessing a lot of arguments automatically.
|
31
|
+
#
|
29
32
|
|
30
33
|
# Add lib to load path during development
|
31
34
|
$: << '../lib/'
|
@@ -46,9 +49,5 @@ random = devs[rand(devs.size)]
|
|
46
49
|
random_device = bus.get_object('org.freedesktop.Hal',random)
|
47
50
|
random_device.interface!('org.freedesktop.Hal.Device')
|
48
51
|
|
49
|
-
# Define method manually, as HAL doesn't provide introspection, at least
|
50
|
-
# in my version.
|
51
|
-
random_device.method!(:GetProperty, 's')
|
52
|
-
|
53
52
|
# Print info and device path:
|
54
53
|
puts ("#{random_device.GetProperty('info.product')} (#{random})")
|
data/lib/rbus/bus/bus.rb
CHANGED
@@ -46,9 +46,8 @@ module RBus
|
|
46
46
|
# Represents a connection to a Bus. It is also a Proxy object for
|
47
47
|
# sending messages to the bus itself.
|
48
48
|
class Bus < Proxy
|
49
|
-
NAMES = []
|
50
49
|
|
51
|
-
attr_reader :message_loop
|
50
|
+
attr_reader :message_loop, :transport, :names
|
52
51
|
|
53
52
|
# Connect to Bus with +server_address+, which can contain multiple
|
54
53
|
# addresses to try, separated by semicolons.
|
@@ -63,17 +62,16 @@ module RBus
|
|
63
62
|
# Not used for anything, save at all?
|
64
63
|
@guid = Auth.authorize(@transport)
|
65
64
|
|
66
|
-
#
|
67
|
-
|
68
|
-
@message_loop = Mainloop.new(@transport)
|
65
|
+
# Setup mainloop.
|
66
|
+
@message_loop = Mainloop.new(self)
|
69
67
|
|
70
68
|
@well_known_name = 'org.freedesktop.DBus'
|
71
69
|
@object_path = '/org/freedesktop/DBus'
|
72
70
|
@interface = 'org.freedesktop.DBus'
|
73
|
-
|
71
|
+
@names = [ Hello() ]
|
74
72
|
Introspect()
|
75
73
|
|
76
|
-
Log.debug('Bus names:',
|
74
|
+
Log.debug('Bus names:', @names)
|
77
75
|
|
78
76
|
end
|
79
77
|
|
data/lib/rbus/bus/proxy.rb
CHANGED
@@ -22,21 +22,32 @@
|
|
22
22
|
#++
|
23
23
|
#
|
24
24
|
require 'rexml/document'
|
25
|
+
require File.join(File.dirname(__FILE__), '..', 'etc', 'blankslate')
|
25
26
|
|
26
27
|
module RBus
|
27
28
|
|
28
29
|
VALID_METHOD_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,254}$/
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
PREFIX_TO_SIG = {
|
31
|
+
'byte' => 'y',
|
32
|
+
'boolean' => 'b',
|
33
|
+
'int16' => 'n',
|
34
|
+
'uint16' => 'q',
|
35
|
+
'int32' => 'i',
|
36
|
+
'uint32' => 'u',
|
37
|
+
'int64' => 'x',
|
38
|
+
'uint64' => 't',
|
39
|
+
'double' => 'd',
|
40
|
+
'string' => 's',
|
41
|
+
'objpath' => 'o',
|
42
|
+
'signature' => 'g',
|
43
|
+
'variant' => 'v',
|
44
|
+
'array' => 'a',
|
45
|
+
'dict' => 'a{',
|
46
|
+
}
|
36
47
|
|
37
48
|
# The object that represents the remote bus object.
|
38
49
|
class Proxy < BlankSlate
|
39
|
-
|
50
|
+
|
40
51
|
# Parses Introspect() XML into a hash with
|
41
52
|
# {method => signature}
|
42
53
|
def self.parse_introspect(xml)
|
@@ -52,7 +63,7 @@ module RBus
|
|
52
63
|
end
|
53
64
|
methods
|
54
65
|
end
|
55
|
-
|
66
|
+
|
56
67
|
def initialize(bus, well_known_name, object_path)
|
57
68
|
@bus = bus
|
58
69
|
@message_loop = @bus.message_loop
|
@@ -60,7 +71,6 @@ module RBus
|
|
60
71
|
@object_path = object_path
|
61
72
|
Introspect()
|
62
73
|
end
|
63
|
-
|
64
74
|
def Introspect # :nodoc:
|
65
75
|
# TODO: store interfaces as well, if ever needed
|
66
76
|
interface = @interface
|
@@ -107,6 +117,77 @@ module RBus
|
|
107
117
|
def method!(name, signature)
|
108
118
|
@methods[name.to_s] = signature
|
109
119
|
end
|
120
|
+
|
121
|
+
# Parse arguments and guess signature from a few types
|
122
|
+
# Handles [dr]bus-send type arguments also
|
123
|
+
def parse_arguments!(arguments)
|
124
|
+
|
125
|
+
strip = lambda{|s|s.sub!(/^'/,'');s.sub!(/'$/,'')}
|
126
|
+
|
127
|
+
signature = ''
|
128
|
+
array = false
|
129
|
+
arguments.map! do |value|
|
130
|
+
case value
|
131
|
+
when TrueClass, FalseClass
|
132
|
+
signature << 'b'
|
133
|
+
when Float
|
134
|
+
signature << 'd'
|
135
|
+
when Hash
|
136
|
+
signature << 'a{'
|
137
|
+
fail "Can't guess signature for empty hash" if value.empty?
|
138
|
+
k_sig = parse_arguments!([value.keys.first])
|
139
|
+
v_sig = parse_arguments!([value.values.first])
|
140
|
+
signature << k_sig
|
141
|
+
signature << v_sig
|
142
|
+
signature << '}'
|
143
|
+
when Array
|
144
|
+
a_sig = parse_arguments!(value)
|
145
|
+
#puts a_sig
|
146
|
+
|
147
|
+
# TODO: this only covers simple types
|
148
|
+
sq = a_sig.squeeze
|
149
|
+
if sq.length == 1 || sq[0] == ?a && sq.length == 2
|
150
|
+
signature << 'a' << sq
|
151
|
+
else
|
152
|
+
signature << "(#{a_sig})"
|
153
|
+
end
|
154
|
+
when Symbol
|
155
|
+
signature << 's'
|
156
|
+
when String
|
157
|
+
type, arg = value.split(':',2)
|
158
|
+
if PREFIX_TO_SIG.has_key?(type)
|
159
|
+
signature << PREFIX_TO_SIG[type]
|
160
|
+
strip.call(arg)
|
161
|
+
case type
|
162
|
+
when 'dict'
|
163
|
+
key_s,val_s,arg = arg.split(':',3)
|
164
|
+
strip.call(arg)
|
165
|
+
value = arg.nil? ? {} : Hash[*arg.split(/'?,'?/)]
|
166
|
+
signature << PREFIX_TO_SIG[key_s]
|
167
|
+
signature << PREFIX_TO_SIG[val_s]
|
168
|
+
signature << '}'
|
169
|
+
when 'array'
|
170
|
+
array = true
|
171
|
+
value = arg
|
172
|
+
redo
|
173
|
+
when 'variant'
|
174
|
+
value = arg
|
175
|
+
redo
|
176
|
+
else
|
177
|
+
value = (array) ? arg.split(/'?,'?/) : arg
|
178
|
+
array = false
|
179
|
+
end
|
180
|
+
else
|
181
|
+
signature << 's'
|
182
|
+
end
|
183
|
+
else
|
184
|
+
fail "Failed to guess signature for '#{value.class}'"
|
185
|
+
end
|
186
|
+
value
|
187
|
+
end
|
188
|
+
|
189
|
+
return signature
|
190
|
+
end
|
110
191
|
|
111
192
|
# Routes all method calls to remote object
|
112
193
|
def method_missing(name, *args, &block) # :nodoc:
|
@@ -124,14 +205,25 @@ module RBus
|
|
124
205
|
m.object_path = @object_path
|
125
206
|
m.interface = @interface if @interface
|
126
207
|
m.member = method
|
127
|
-
|
128
|
-
|
208
|
+
if !args.empty?
|
209
|
+
begin
|
210
|
+
# always walk arguments because 'key:value' is always a valid arg
|
211
|
+
signature = parse_arguments!(args)
|
212
|
+
rescue RuntimeError => e
|
213
|
+
# re-bomb unless other signature
|
214
|
+
raise e unless @methods.has_key?(method)
|
215
|
+
end
|
216
|
+
if !@methods.has_key?(method)
|
217
|
+
method!(name, signature)
|
218
|
+
end
|
129
219
|
Log.debug('Signature: ' + @methods[method])
|
130
220
|
m.signature = @methods[method]
|
131
221
|
end
|
222
|
+
m.arguments = args
|
132
223
|
end
|
133
224
|
Log.debug(block_given? ? 'Block given' : 'Block NOT given')
|
134
225
|
@message_loop.send_message(call, block_given? ? block : nil)
|
135
226
|
end
|
136
227
|
end
|
137
228
|
end
|
229
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module RBus
|
2
|
+
# BlankSlate is a superclass that empties (almost) all instance methods
|
3
|
+
# from it's subclasses.
|
4
|
+
# See: http://onestepback.org/index.cgi/Tech/Ruby/BlankSlate.rdoc
|
5
|
+
class BlankSlate
|
6
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__|\W$|^should/ }
|
7
|
+
end
|
8
|
+
end
|
data/lib/rbus/etc/version.rb
CHANGED
@@ -30,9 +30,10 @@ module RBus
|
|
30
30
|
include Observable
|
31
31
|
include MonitorMixin
|
32
32
|
|
33
|
-
def initialize(
|
33
|
+
def initialize(bus)
|
34
34
|
super()
|
35
|
-
@
|
35
|
+
@bus = bus
|
36
|
+
@transport = @bus.transport
|
36
37
|
@writer = Message::Writer.new(@transport)
|
37
38
|
@reader = Message::Reader.new(@transport)
|
38
39
|
setup
|
@@ -50,10 +51,10 @@ module RBus
|
|
50
51
|
def handle_incoming(message)
|
51
52
|
return if message.nil?
|
52
53
|
|
53
|
-
# -
|
54
|
-
# - empty
|
55
|
-
# - otherwise,
|
56
|
-
return unless
|
54
|
+
# - names.nil? is when Bus is connecting only
|
55
|
+
# - destination.empty? is for signals only
|
56
|
+
# - otherwise, names must include the destination
|
57
|
+
return unless @bus.names.nil? || message.destination.nil? || @bus.names.include?(message.destination)
|
57
58
|
|
58
59
|
# The audience is listening... broadcast the new message.
|
59
60
|
changed
|
data/spec/bus_spec.rb
CHANGED
@@ -25,7 +25,6 @@ require File.dirname(__FILE__) + '/helpers/spec_helper'
|
|
25
25
|
require File.dirname(__FILE__) + '/helpers/bus_mocks'
|
26
26
|
|
27
27
|
module RBus
|
28
|
-
|
29
28
|
module BusSpecHelper
|
30
29
|
def setup_mocks
|
31
30
|
@transport = mock('Transport')
|
@@ -37,7 +36,6 @@ module RBus
|
|
37
36
|
Message::Reader.stub!(:new).and_return(@message_reader)
|
38
37
|
|
39
38
|
message_loop = mock('Mainloop', :null_object => true)
|
40
|
-
#message_loop.stub!(:run).and_return(message_loop)
|
41
39
|
message_loop.stub!(:send_message)
|
42
40
|
Mainloop.stub!(:new).and_return(message_loop)
|
43
41
|
|
@@ -45,7 +43,8 @@ module RBus
|
|
45
43
|
Bus.stub!(:get_object).and_return(@proxy)
|
46
44
|
|
47
45
|
Transport.stub!(:connect).and_return(@transport)
|
48
|
-
Auth.stub!(:authorize).and_return(fake_guid)
|
46
|
+
Auth.stub!(:authorize).and_return(fake_guid)
|
47
|
+
|
49
48
|
end
|
50
49
|
|
51
50
|
def fake_guid
|
@@ -61,15 +60,15 @@ module RBus
|
|
61
60
|
end
|
62
61
|
|
63
62
|
specify "should be a Bus object" do
|
64
|
-
@bus.
|
63
|
+
@bus.should be_an_instance_of(Bus)
|
65
64
|
end
|
66
65
|
|
67
66
|
specify "should respond to get_object" do
|
68
|
-
@bus.
|
67
|
+
@bus.should respond_to(:get_object)
|
69
68
|
end
|
70
69
|
|
71
70
|
specify "should barf on empty address" do
|
72
|
-
lambda{Bus.new('')}.
|
71
|
+
lambda{Bus.new('')}.should raise_error(InvalidAddressException)
|
73
72
|
end
|
74
73
|
|
75
74
|
end
|
@@ -94,15 +93,15 @@ module RBus
|
|
94
93
|
end
|
95
94
|
|
96
95
|
specify "should be a Bus object" do
|
97
|
-
@bus.
|
96
|
+
@bus.should be_a_kind_of(Bus)
|
98
97
|
end
|
99
98
|
|
100
99
|
specify "should be a singleton" do
|
101
|
-
@bus.should
|
100
|
+
@bus.should equal(RBus.session_bus)
|
102
101
|
end
|
103
102
|
|
104
103
|
specify "should be a SessionBus object" do
|
105
|
-
@bus.
|
104
|
+
@bus.should be_an_instance_of(SessionBus)
|
106
105
|
end
|
107
106
|
|
108
107
|
end
|
@@ -132,8 +131,6 @@ module RBus
|
|
132
131
|
|
133
132
|
end
|
134
133
|
|
135
|
-
|
136
|
-
|
137
134
|
context "System bus" do
|
138
135
|
include BusSpecHelper
|
139
136
|
setup do
|
@@ -142,15 +139,15 @@ module RBus
|
|
142
139
|
end
|
143
140
|
|
144
141
|
specify "should be a Bus object" do
|
145
|
-
@bus.
|
142
|
+
@bus.should be_a_kind_of(Bus)
|
146
143
|
end
|
147
144
|
|
148
145
|
specify "should be a singleton" do
|
149
|
-
@bus.should
|
146
|
+
@bus.should equal(RBus.system_bus)
|
150
147
|
end
|
151
148
|
|
152
149
|
specify "should be a SystemBus object" do
|
153
|
-
@bus.
|
150
|
+
@bus.should be_an_instance_of(SystemBus)
|
154
151
|
end
|
155
152
|
|
156
153
|
end
|
data/spec/mainloop_spec.rb
CHANGED
@@ -30,13 +30,16 @@ module RBus
|
|
30
30
|
@transport = mock('Transport')
|
31
31
|
@transport.stub!(:send)
|
32
32
|
@transport.stub!(:read)
|
33
|
-
|
33
|
+
|
34
|
+
@bus = mock('Bus')
|
35
|
+
@bus.stub!(:transport).and_return(@transport)
|
36
|
+
@bus.stub!(:names).and_return([':1.31'])
|
37
|
+
|
34
38
|
@message = mock('Message', :null_object => true)
|
35
39
|
@message.stub!(:serial).and_return(1)
|
36
40
|
@message.stub!(:message).and_return("string")
|
37
41
|
|
38
42
|
@message.stub!(:destination).and_return(":1.31")
|
39
|
-
Bus::NAMES[0] = ':1.31'
|
40
43
|
|
41
44
|
@message_reader = mock('Message::Reader', :null_object => true)
|
42
45
|
@message_reader.stub!(:read_message).and_return(@message)
|
@@ -46,7 +49,7 @@ module RBus
|
|
46
49
|
@message_writer.stub!(:send_message)
|
47
50
|
Writer::stub!(:new).and_return(@message_writer)
|
48
51
|
|
49
|
-
@message_loop = Mainloop.new(@
|
52
|
+
@message_loop = Mainloop.new(@bus)
|
50
53
|
|
51
54
|
Thread.abort_on_exception = true
|
52
55
|
end
|
data/spec/message_spec.rb
CHANGED
data/spec/proxy_spec.rb
CHANGED
@@ -62,6 +62,7 @@ module RBus
|
|
62
62
|
m.arguments.should == ['a string',2,3,[2,3]]
|
63
63
|
b.should == nil
|
64
64
|
}
|
65
|
+
@proxy.method!(:Hola, 'suuau')
|
65
66
|
@proxy.Hola('a string', 2,3,[2,3])
|
66
67
|
end
|
67
68
|
|
@@ -115,6 +116,75 @@ module RBus
|
|
115
116
|
specify "should raise on too long name (>255)" do
|
116
117
|
lambda{@proxy.abcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijk}.should_raise(InvalidNameException)
|
117
118
|
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
context "Signature guesses" do
|
123
|
+
setup do
|
124
|
+
@well_known_name = 'org.rubyforge.rbus'
|
125
|
+
@object_path = '/org/rubyforge/rbus'
|
126
|
+
@message_loop = mock('MessageLoop')
|
127
|
+
@message_loop.stub!(:send_message)
|
128
|
+
@bus = mock('Bus')
|
129
|
+
@bus.stub!(:message_loop).and_return(@message_loop)
|
130
|
+
@proxy = Proxy.new(@bus, @well_known_name, @object_path)
|
131
|
+
end
|
132
|
+
|
133
|
+
specify "should parse mixed singles" do
|
134
|
+
args = [true, false,'something','string:string2', 'uint32:13']
|
135
|
+
@proxy.parse_arguments!(args).should == 'bbssu'
|
136
|
+
args.should == [true,false,'something','string2', '13']
|
137
|
+
end
|
138
|
+
|
139
|
+
specify "should parse struct of int,string" do
|
140
|
+
args = [['int32:-13','12']]
|
141
|
+
@proxy.parse_arguments!(args).should == '(is)'
|
142
|
+
args.should == [['-13','12']]
|
143
|
+
end
|
144
|
+
|
145
|
+
specify "should parse array of ints" do
|
146
|
+
args = [['int32:-13','int32:12']]
|
147
|
+
@proxy.parse_arguments!(args).should == 'ai'
|
148
|
+
args.should == [['-13','12']]
|
149
|
+
end
|
118
150
|
|
151
|
+
specify "should parse array of array of string" do
|
152
|
+
args = [[['','12']]]
|
153
|
+
@proxy.parse_arguments!(args).should == 'aas'
|
154
|
+
end
|
155
|
+
|
156
|
+
specify "should parse array of string" do
|
157
|
+
args = ["array:string:'foo','bar'"]
|
158
|
+
@proxy.parse_arguments!(args).should == 'as'
|
159
|
+
args.should == [['foo','bar']]
|
160
|
+
end
|
161
|
+
|
162
|
+
specify "should parse dict of string => uint32" do
|
163
|
+
args = ["dict:string:uint32:'foo',32,'bar',64"]
|
164
|
+
@proxy.parse_arguments!(args).should == 'a{su}'
|
165
|
+
args.should == [{'foo' => '32', 'bar' => '64'}]
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
specify "should parse hash with s => s" do
|
170
|
+
args = [{'a' => 'a', 'b' => 'c'}]
|
171
|
+
@proxy.parse_arguments!(args).should == 'a{ss}'
|
172
|
+
end
|
173
|
+
|
174
|
+
specify "should parse hash with s => as" do
|
175
|
+
args = [{:koss => ['haha'], 'bass' => ['lass']}]
|
176
|
+
@proxy.parse_arguments!(args).should == 'a{sas}'
|
177
|
+
end
|
178
|
+
|
179
|
+
specify "should fail on parse empty hash" do
|
180
|
+
args = [{}]
|
181
|
+
lambda{@proxy.parse_arguments!(args)}.should_raise
|
182
|
+
end
|
183
|
+
|
184
|
+
specify "should parse float" do
|
185
|
+
args = [1.23]
|
186
|
+
@proxy.parse_arguments!(args).should == 'd'
|
187
|
+
end
|
188
|
+
|
119
189
|
end
|
120
190
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rbus
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date: 2007-03-
|
6
|
+
version: 0.1.1
|
7
|
+
date: 2007-03-30 00:00:00 +02:00
|
8
8
|
summary: A native implementation of the D-Bus protocol.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/rbus/bus/proxy.rb
|
60
60
|
- lib/rbus/bus/transport.rb
|
61
61
|
- lib/rbus/default.rb
|
62
|
+
- lib/rbus/etc/blankslate.rb
|
62
63
|
- lib/rbus/etc/exception.rb
|
63
64
|
- lib/rbus/etc/log.rb
|
64
65
|
- lib/rbus/etc/types.rb
|