ruby-dbus 0.5.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.
- data/COPYING +504 -0
- data/NEWS +137 -0
- data/README +53 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/doc/tutorial/index.html +356 -0
- data/doc/tutorial/index.markdown +467 -0
- data/examples/gdbus/gdbus +255 -0
- data/examples/gdbus/gdbus.glade +184 -0
- data/examples/gdbus/launch.sh +4 -0
- data/examples/no-introspect/nm-test.rb +21 -0
- data/examples/no-introspect/tracker-test.rb +16 -0
- data/examples/rhythmbox/playpause.rb +25 -0
- data/examples/service/call_service.rb +25 -0
- data/examples/service/service_newapi.rb +51 -0
- data/examples/simple/call_introspect.rb +34 -0
- data/examples/utils/listnames.rb +11 -0
- data/examples/utils/notify.rb +19 -0
- data/lib/dbus.rb +91 -0
- data/lib/dbus/auth.rb +258 -0
- data/lib/dbus/bus.rb +816 -0
- data/lib/dbus/core_ext/class/attribute.rb +91 -0
- data/lib/dbus/core_ext/kernel/singleton_class.rb +14 -0
- data/lib/dbus/core_ext/module/remove_method.rb +12 -0
- data/lib/dbus/error.rb +44 -0
- data/lib/dbus/export.rb +132 -0
- data/lib/dbus/introspect.rb +553 -0
- data/lib/dbus/marshall.rb +443 -0
- data/lib/dbus/matchrule.rb +100 -0
- data/lib/dbus/message.rb +310 -0
- data/lib/dbus/type.rb +222 -0
- data/ruby-dbus.gemspec +18 -0
- data/test/binding_test.rb +56 -0
- data/test/bus_driver_test.rb +22 -0
- data/test/dbus-launch-simple +35 -0
- data/test/dbus-limited-session.conf +28 -0
- data/test/server_robustness_test.rb +41 -0
- data/test/server_test.rb +53 -0
- data/test/service_newapi.rb +129 -0
- data/test/session_bus_test_manual.rb +20 -0
- data/test/signal_test.rb +64 -0
- data/test/t1 +4 -0
- data/test/t2.rb +66 -0
- data/test/t3-ticket27.rb +18 -0
- data/test/t5-report-dbus-interface.rb +58 -0
- data/test/t6-loop.rb +82 -0
- data/test/test_env +13 -0
- data/test/test_server +39 -0
- data/test/variant_test.rb +66 -0
- metadata +117 -0
data/ruby-dbus.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
require "rubygems"
|
3
|
+
require "rake"
|
4
|
+
|
5
|
+
GEMSPEC = Gem::Specification.new do |s|
|
6
|
+
s.name = "ruby-dbus"
|
7
|
+
# s.rubyforge_project = nil
|
8
|
+
s.summary = "Ruby module for interaction with D-Bus"
|
9
|
+
# s.description = FIXME
|
10
|
+
s.version = File.read("VERSION").strip
|
11
|
+
s.author = "Ruby DBus Team"
|
12
|
+
s.email = "ruby-dbus-devel@lists.luon.net"
|
13
|
+
s.homepage = "http://trac.luon.net/data/ruby-dbus/"
|
14
|
+
s.files = FileList["{doc/tutorial,examples,lib,test}/**/*", "Rakefile", "ruby-dbus.gemspec", "VERSION"].to_a.sort
|
15
|
+
s.require_path = "lib"
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ["COPYING", "README", "NEWS"]
|
18
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test the binding of dbus concepts to ruby concepts
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
class BindingTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@bus = DBus::SessionBus.instance
|
9
|
+
@svc = @bus.service("org.ruby.service")
|
10
|
+
@base = @svc.object "/org/ruby/MyInstance"
|
11
|
+
@base.introspect
|
12
|
+
@base.default_iface = "org.ruby.SampleInterface"
|
13
|
+
end
|
14
|
+
|
15
|
+
# https://trac.luon.net/ruby-dbus/ticket/36#comment:3
|
16
|
+
def test_class_inheritance
|
17
|
+
derived = @svc.object "/org/ruby/MyDerivedInstance"
|
18
|
+
derived.introspect
|
19
|
+
|
20
|
+
# it should inherit from the parent
|
21
|
+
assert_not_nil derived["org.ruby.SampleInterface"]
|
22
|
+
end
|
23
|
+
|
24
|
+
# https://trac.luon.net/ruby-dbus/ticket/36
|
25
|
+
# Interfaces and methods/signals appeared on all classes
|
26
|
+
def test_separation_of_classes
|
27
|
+
test2 = @svc.object "/org/ruby/MyInstance2"
|
28
|
+
test2.introspect
|
29
|
+
|
30
|
+
# it should have its own interface
|
31
|
+
assert_not_nil test2["org.ruby.Test2"]
|
32
|
+
# but not an interface of the Test class
|
33
|
+
assert_nil test2["org.ruby.SampleInterface"]
|
34
|
+
|
35
|
+
# and the parent should not get polluted by the child
|
36
|
+
assert_nil @base["org.ruby.Test2"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_translating_errors_into_exceptions
|
40
|
+
# this is a generic call that will reply with the specified error
|
41
|
+
@base.Error "org.example.Fail", "as you wish"
|
42
|
+
assert false, "should have raised"
|
43
|
+
rescue DBus::Error => e
|
44
|
+
assert_equal "org.example.Fail", e.name
|
45
|
+
assert_equal "as you wish", e.message
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_generic_dbus_error
|
49
|
+
# this is a generic call that will reply with the specified error
|
50
|
+
@base.will_raise_error_failed
|
51
|
+
assert false, "should have raised"
|
52
|
+
rescue DBus::Error => e
|
53
|
+
assert_equal "org.freedesktop.DBus.Error.Failed", e.name
|
54
|
+
assert_equal "failed as designed", e.message
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test the methods of the bus driver
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
def d(msg)
|
7
|
+
puts msg if $DEBUG
|
8
|
+
end
|
9
|
+
|
10
|
+
class BusDriverTest < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@bus = DBus::SessionBus.instance
|
13
|
+
@svc = @bus.service("org.ruby.service")
|
14
|
+
@svc.object("/").introspect
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_exists
|
18
|
+
assert @svc.exists?, "could not find the service"
|
19
|
+
nonsvc = @bus.service "org.ruby.nosuchservice"
|
20
|
+
assert ! nonsvc.exists?, "found a service that should not exist"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#! /bin/sh
|
2
|
+
# A wrapper for DBus tests
|
3
|
+
# Reimplementing dbus-launch because it is in dbus-1-x11.rpm
|
4
|
+
# Sets up a private session bus and call the specified program
|
5
|
+
set -o errexit
|
6
|
+
|
7
|
+
# This launches the bus daemon,
|
8
|
+
# exports DBUS_SESSION_BUS_ADDRESS and sets DBUS_SESSION_BUS_PID
|
9
|
+
my_dbus_launch () {
|
10
|
+
# reimplementing dbus-launch because it is in dbus-1-x11.rpm
|
11
|
+
PF=`mktemp dbus.pid.XXXXXX` || exit
|
12
|
+
AF=`mktemp dbus.addr.XXXXXX` || exit
|
13
|
+
RM_FILES="$RM_FILES $PF $AF"
|
14
|
+
|
15
|
+
dbus-daemon --config-file=dbus-limited-session.conf --print-address=3 3>$AF --print-pid=4 4>$PF &
|
16
|
+
# wait for the daemon to print the info
|
17
|
+
TRIES=0
|
18
|
+
while [ ! -s $AF -o ! -s $PF ]; do
|
19
|
+
sleep 0.1
|
20
|
+
TRIES=`expr $TRIES + 1`
|
21
|
+
if [ $TRIES -gt 100 ]; then echo "dbus-daemon failed?"; exit 1; fi
|
22
|
+
done
|
23
|
+
DBUS_SESSION_BUS_PID=$(cat $PF)
|
24
|
+
export DBUS_SESSION_BUS_ADDRESS=$(cat $AF)
|
25
|
+
KILLS="$KILLS $DBUS_SESSION_BUS_PID"
|
26
|
+
# dbus-monitor &
|
27
|
+
}
|
28
|
+
|
29
|
+
my_dbus_launch
|
30
|
+
|
31
|
+
# Clean up at exit.
|
32
|
+
trap "kill \$KILLS; rm -rf \$RM_FILES" EXIT TERM INT
|
33
|
+
|
34
|
+
# run the payload; the return value is passed on
|
35
|
+
"$@"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<!-- This configuration file controls the testing message bus.
|
2
|
+
It is based on a session bus config. -->
|
3
|
+
|
4
|
+
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
|
5
|
+
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
6
|
+
<busconfig>
|
7
|
+
<!-- Our well-known bus type, don't change this -->
|
8
|
+
<type>session</type>
|
9
|
+
|
10
|
+
<listen>unix:tmpdir=/tmp</listen>
|
11
|
+
<listen>tcp:host=localhost,port=0,family=ipv4</listen>
|
12
|
+
|
13
|
+
<standard_session_servicedirs />
|
14
|
+
|
15
|
+
<policy context="default">
|
16
|
+
<!-- Allow everything to be sent -->
|
17
|
+
<allow send_destination="*" eavesdrop="true"/>
|
18
|
+
<!-- Allow everything to be received -->
|
19
|
+
<allow eavesdrop="true"/>
|
20
|
+
<!-- Allow anyone to own anything -->
|
21
|
+
<allow own="*"/>
|
22
|
+
</policy>
|
23
|
+
|
24
|
+
<!-- Do not increase the limits.
|
25
|
+
Instead, lower some so that we can test resource leaks. -->
|
26
|
+
<limit name="max_match_rules_per_connection">50</limit><!-- was 512 -->
|
27
|
+
|
28
|
+
</busconfig>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test that a server survives various error cases
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
class ServerRobustnessTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@bus = DBus::SessionBus.instance
|
9
|
+
@svc = @bus.service("org.ruby.service")
|
10
|
+
end
|
11
|
+
|
12
|
+
# https://trac.luon.net/ruby-dbus/ticket/31
|
13
|
+
# the server should not crash
|
14
|
+
def test_no_such_path_with_introspection
|
15
|
+
obj = @svc.object "/org/ruby/NotMyInstance"
|
16
|
+
obj.introspect
|
17
|
+
assert false, "should have raised"
|
18
|
+
rescue DBus::Error => e
|
19
|
+
assert_no_match(/timeout/, e.to_s)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_no_such_path_without_introspection
|
23
|
+
obj = @svc.object "/org/ruby/NotMyInstance"
|
24
|
+
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.SampleInterface")
|
25
|
+
ifc.define_method("the_answer", "out n:i")
|
26
|
+
ifc.the_answer
|
27
|
+
assert false, "should have raised"
|
28
|
+
rescue DBus::Error => e
|
29
|
+
assert_no_match(/timeout/, e.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_a_method_that_raises
|
33
|
+
obj = @svc.object "/org/ruby/MyInstance"
|
34
|
+
obj.introspect
|
35
|
+
obj.default_iface = "org.ruby.SampleInterface"
|
36
|
+
obj.will_raise
|
37
|
+
assert false, "should have raised"
|
38
|
+
rescue DBus::Error => e
|
39
|
+
assert_no_match(/timeout/, e.to_s)
|
40
|
+
end
|
41
|
+
end
|
data/test/server_test.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test that a server survives various error cases
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
class Foo < DBus::Object
|
7
|
+
dbus_interface "org.ruby.ServerTest" do
|
8
|
+
dbus_signal :signal_without_arguments
|
9
|
+
dbus_signal :signal_with_argument, "epsilon:d"
|
10
|
+
end
|
11
|
+
|
12
|
+
dbus_signal :signal_without_interface
|
13
|
+
rescue DBus::Object::UndefinedInterface => e
|
14
|
+
# raised by the preceding signal declaration
|
15
|
+
end
|
16
|
+
|
17
|
+
class Bar < DBus::Object
|
18
|
+
dbus_interface "org.ruby.ServerTest" do
|
19
|
+
# a valid Ruby symbol but an invalid DBus name; Ticket#38
|
20
|
+
dbus_signal :signal_with_a_bang!
|
21
|
+
end
|
22
|
+
rescue DBus::InvalidMethodName
|
23
|
+
# raised by the preceding signal declaration
|
24
|
+
end
|
25
|
+
|
26
|
+
class ServerTest < Test::Unit::TestCase
|
27
|
+
def setup
|
28
|
+
@bus = DBus::SessionBus.instance
|
29
|
+
@svc = @bus.request_service "org.ruby.server-test"
|
30
|
+
end
|
31
|
+
|
32
|
+
def teardown
|
33
|
+
@bus.proxy.ReleaseName "org.ruby.server-test"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_unexporting_an_object
|
37
|
+
obj = Foo.new "/org/ruby/Foo"
|
38
|
+
@svc.export obj
|
39
|
+
assert @svc.unexport(obj)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_unexporting_an_object_not_exported
|
43
|
+
obj = Foo.new "/org/ruby/Foo"
|
44
|
+
assert !@svc.unexport(obj)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_emiting_signals
|
48
|
+
obj = Foo.new "/org/ruby/Foo"
|
49
|
+
@svc.export obj
|
50
|
+
obj.signal_without_arguments
|
51
|
+
obj.signal_with_argument(-0.1)
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# find the library without external help
|
4
|
+
$:.unshift File.expand_path("../../lib", __FILE__)
|
5
|
+
|
6
|
+
require 'dbus'
|
7
|
+
|
8
|
+
def d(msg)
|
9
|
+
puts "#{$$} #{msg}" if $DEBUG
|
10
|
+
end
|
11
|
+
|
12
|
+
class Test < DBus::Object
|
13
|
+
# Create an interface aggregating all upcoming dbus_method defines.
|
14
|
+
dbus_interface "org.ruby.SampleInterface" do
|
15
|
+
dbus_method :hello, "in name:s, in name2:s" do |name, name2|
|
16
|
+
puts "hello(#{name}, #{name2})"
|
17
|
+
end
|
18
|
+
|
19
|
+
dbus_method :test_variant, "in stuff:v" do |variant|
|
20
|
+
p variant
|
21
|
+
end
|
22
|
+
|
23
|
+
dbus_method :bounce_variant, "in stuff:v, out chaff:v" do |variant|
|
24
|
+
[variant]
|
25
|
+
end
|
26
|
+
|
27
|
+
dbus_method :variant_size, "in stuff:v, out size:u" do |variant|
|
28
|
+
[variant.size]
|
29
|
+
end
|
30
|
+
|
31
|
+
dbus_method :the_answer, "out answer:i" do
|
32
|
+
42
|
33
|
+
end
|
34
|
+
|
35
|
+
dbus_method :will_raise, "" do
|
36
|
+
raise "Handle this"
|
37
|
+
end
|
38
|
+
|
39
|
+
dbus_method :will_raise_error_failed, "" do
|
40
|
+
raise DBus.error, "failed as designed"
|
41
|
+
end
|
42
|
+
|
43
|
+
dbus_method :Error, "in name:s, in description:s" do |name, description|
|
44
|
+
raise DBus.error(name), description
|
45
|
+
end
|
46
|
+
|
47
|
+
dbus_signal :SomethingJustHappened, "toto:s, tutu:u"
|
48
|
+
end
|
49
|
+
|
50
|
+
dbus_interface "org.ruby.AnotherInterface" do
|
51
|
+
dbus_method :ThatsALongMethodNameIThink do
|
52
|
+
puts "ThatsALongMethodNameIThink"
|
53
|
+
end
|
54
|
+
dbus_method :Reverse, "in instr:s, out outstr:s" do |instr|
|
55
|
+
outstr = instr.split(//).reverse.join
|
56
|
+
puts "got: #{instr}, replying: #{outstr}"
|
57
|
+
[outstr]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
dbus_interface "org.ruby.Ticket30" do
|
62
|
+
dbus_method :Sybilla, 'in choices:av, out advice:s' do |choices|
|
63
|
+
["Do #{choices[0]}"]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
dbus_interface "org.ruby.Loop" do
|
68
|
+
# starts doing something long, but returns immediately
|
69
|
+
# and sends a signal when done
|
70
|
+
dbus_method :LongTaskBegin, 'in delay:i' do |delay|
|
71
|
+
# FIXME did not complain about mismatch between signature and block args
|
72
|
+
d "Long task began"
|
73
|
+
task = Thread.new do
|
74
|
+
d "Long task thread started (#{delay}s)"
|
75
|
+
sleep delay
|
76
|
+
d "Long task will signal end"
|
77
|
+
self.LongTaskEnd
|
78
|
+
end
|
79
|
+
task.abort_on_exception = true # protect from test case bugs
|
80
|
+
end
|
81
|
+
|
82
|
+
dbus_signal :LongTaskEnd
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class Derived < Test
|
87
|
+
end
|
88
|
+
|
89
|
+
class Test2 < DBus::Object
|
90
|
+
dbus_interface "org.ruby.Test2" do
|
91
|
+
dbus_method :hi, "in name:s, out greeting:s" do |name|
|
92
|
+
"Hi, #{name}!"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
bus = DBus::SessionBus.instance
|
98
|
+
service = bus.request_service("org.ruby.service")
|
99
|
+
myobj = Test.new("/org/ruby/MyInstance")
|
100
|
+
service.export(myobj)
|
101
|
+
derived = Derived.new "/org/ruby/MyDerivedInstance"
|
102
|
+
service.export derived
|
103
|
+
test2 = Test2.new "/org/ruby/MyInstance2"
|
104
|
+
service.export test2
|
105
|
+
|
106
|
+
# introspect every other connection, Ticket #34
|
107
|
+
# (except the one that activates us - it has already emitted
|
108
|
+
# NOC by the time we run this. Therefore the test for #34 will not work
|
109
|
+
# by running t2.rb alone, one has to run t1 before it; 'rake' does it)
|
110
|
+
mr = DBus::MatchRule.new.from_s "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
|
111
|
+
bus.add_match(mr) do |msg|
|
112
|
+
new_unique_name = msg.params[2]
|
113
|
+
unless new_unique_name.empty?
|
114
|
+
d "RRRING #{new_unique_name}"
|
115
|
+
bus.introspect_data(new_unique_name, "/") do
|
116
|
+
# ignore the result
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
puts "listening"
|
122
|
+
main = DBus::Main.new
|
123
|
+
main << bus
|
124
|
+
begin
|
125
|
+
main.run
|
126
|
+
rescue SystemCallError
|
127
|
+
# the test driver will kill the bus, that's OK
|
128
|
+
end
|
129
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "test/unit"
|
3
|
+
require "dbus"
|
4
|
+
|
5
|
+
def d(msg)
|
6
|
+
puts msg if $DEBUG
|
7
|
+
end
|
8
|
+
|
9
|
+
class SessionBusAddressTest < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
# test getting the session bus address even if unset in ENV (Issue#4)
|
12
|
+
ENV.delete "DBUS_SESSION_BUS_ADDRESS"
|
13
|
+
@bus = DBus::SessionBus.instance
|
14
|
+
@svc = @bus.service("org.freedesktop.DBus")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_connection
|
18
|
+
assert @svc.exists?
|
19
|
+
end
|
20
|
+
end
|
data/test/signal_test.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test the signal handlers
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
def d(msg)
|
7
|
+
puts "#{$$} #{msg}" if $DEBUG
|
8
|
+
end
|
9
|
+
|
10
|
+
class SignalHandlerTest < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@session_bus = DBus::SessionBus.instance
|
13
|
+
svc = @session_bus.service("org.ruby.service")
|
14
|
+
@obj = svc.object("/org/ruby/MyInstance")
|
15
|
+
@obj.introspect # necessary
|
16
|
+
@obj.default_iface = "org.ruby.Loop"
|
17
|
+
|
18
|
+
@loop = DBus::Main.new
|
19
|
+
@loop << @session_bus
|
20
|
+
end
|
21
|
+
|
22
|
+
# testing for commit 017c83 (kkaempf)
|
23
|
+
def test_overriding_a_handler
|
24
|
+
counter = 0
|
25
|
+
|
26
|
+
@obj.on_signal "LongTaskEnd" do
|
27
|
+
d "+10"
|
28
|
+
counter += 10
|
29
|
+
end
|
30
|
+
@obj.on_signal "LongTaskEnd" do
|
31
|
+
d "+1"
|
32
|
+
counter += 1
|
33
|
+
end
|
34
|
+
|
35
|
+
d "will begin"
|
36
|
+
@obj.LongTaskBegin 3
|
37
|
+
|
38
|
+
quitter = Thread.new do
|
39
|
+
d "sleep before quit"
|
40
|
+
# FIXME if we sleep for too long
|
41
|
+
# the socket will be drained and we deadlock in a select.
|
42
|
+
# It could be worked around by sending ourselves a Unix signal
|
43
|
+
# (with a dummy handler) to interrupt the select
|
44
|
+
sleep 1
|
45
|
+
d "will quit"
|
46
|
+
@loop.quit
|
47
|
+
end
|
48
|
+
@loop.run
|
49
|
+
|
50
|
+
assert_equal 1, counter
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_too_many_rules
|
54
|
+
100.times do
|
55
|
+
@obj.on_signal "Whichever" do
|
56
|
+
puts "not called"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_removing_a_nonexistent_rule
|
62
|
+
@obj.on_signal "DoesNotExist"
|
63
|
+
end
|
64
|
+
end
|