eventmachine 0.12.2 → 0.12.4

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.
Files changed (125) hide show
  1. data/Rakefile +191 -0
  2. data/{COPYING → docs/COPYING} +0 -0
  3. data/docs/ChangeLog +183 -0
  4. data/{DEFERRABLES → docs/DEFERRABLES} +1 -1
  5. data/{EPOLL → docs/EPOLL} +0 -0
  6. data/{GNU → docs/GNU} +0 -0
  7. data/docs/INSTALL +15 -0
  8. data/{KEYBOARD → docs/KEYBOARD} +0 -0
  9. data/{LEGAL → docs/LEGAL} +0 -0
  10. data/{LIGHTWEIGHT_CONCURRENCY → docs/LIGHTWEIGHT_CONCURRENCY} +1 -1
  11. data/{PURE_RUBY → docs/PURE_RUBY} +1 -1
  12. data/{README → docs/README} +1 -1
  13. data/{RELEASE_NOTES → docs/RELEASE_NOTES} +1 -1
  14. data/{SMTP → docs/SMTP} +1 -1
  15. data/{SPAWNED_PROCESSES → docs/SPAWNED_PROCESSES} +1 -1
  16. data/{TODO → docs/TODO} +1 -1
  17. data/ext/binder.cpp +1 -1
  18. data/ext/binder.h +1 -1
  19. data/ext/cmain.cpp +65 -74
  20. data/ext/cplusplus.cpp +1 -1
  21. data/ext/ed.cpp +41 -25
  22. data/ext/ed.h +10 -3
  23. data/ext/em.cpp +39 -12
  24. data/ext/em.h +13 -1
  25. data/ext/emwin.cpp +1 -1
  26. data/ext/emwin.h +1 -1
  27. data/ext/epoll.cpp +1 -1
  28. data/ext/epoll.h +1 -1
  29. data/ext/eventmachine.h +1 -1
  30. data/ext/eventmachine_cpp.h +1 -1
  31. data/ext/extconf.rb +86 -139
  32. data/ext/fastfilereader/extconf.rb +161 -0
  33. data/ext/fastfilereader/mapper.cpp +202 -0
  34. data/ext/fastfilereader/mapper.h +59 -0
  35. data/ext/fastfilereader/rubymain.cpp +127 -0
  36. data/ext/files.cpp +1 -1
  37. data/ext/files.h +1 -1
  38. data/ext/kb.cpp +1 -1
  39. data/ext/page.cpp +1 -1
  40. data/ext/page.h +1 -1
  41. data/ext/pipe.cpp +14 -7
  42. data/ext/project.h +1 -1
  43. data/ext/rubymain.cpp +56 -2
  44. data/ext/sigs.cpp +1 -1
  45. data/ext/sigs.h +1 -1
  46. data/ext/ssl.cpp +1 -1
  47. data/ext/ssl.h +1 -1
  48. data/java/src/com/rubyeventmachine/Application.java +196 -0
  49. data/java/src/com/rubyeventmachine/Connection.java +74 -0
  50. data/java/src/com/rubyeventmachine/ConnectionFactory.java +37 -0
  51. data/java/src/com/rubyeventmachine/DefaultConnectionFactory.java +46 -0
  52. data/java/src/com/rubyeventmachine/EmReactor.java +408 -0
  53. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  54. data/java/src/com/rubyeventmachine/EventableChannel.java +57 -0
  55. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +171 -0
  56. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +244 -0
  57. data/java/src/com/rubyeventmachine/PeriodicTimer.java +38 -0
  58. data/java/src/com/rubyeventmachine/Timer.java +54 -0
  59. data/java/src/com/rubyeventmachine/tests/ApplicationTest.java +108 -0
  60. data/java/src/com/rubyeventmachine/tests/ConnectTest.java +124 -0
  61. data/java/src/com/rubyeventmachine/tests/EMTest.java +80 -0
  62. data/java/src/com/rubyeventmachine/tests/TestDatagrams.java +53 -0
  63. data/java/src/com/rubyeventmachine/tests/TestServers.java +74 -0
  64. data/java/src/com/rubyeventmachine/tests/TestTimers.java +89 -0
  65. data/lib/em/deferrable.rb +1 -1
  66. data/lib/em/eventable.rb +1 -1
  67. data/lib/em/future.rb +1 -1
  68. data/lib/em/messages.rb +1 -1
  69. data/lib/em/processes.rb +1 -1
  70. data/lib/em/spawnable.rb +1 -1
  71. data/lib/em/streamer.rb +1 -1
  72. data/lib/eventmachine.rb +138 -116
  73. data/lib/eventmachine_version.rb +2 -2
  74. data/lib/evma.rb +1 -1
  75. data/lib/evma/callback.rb +1 -1
  76. data/lib/evma/container.rb +1 -1
  77. data/lib/evma/factory.rb +1 -1
  78. data/lib/evma/protocol.rb +1 -1
  79. data/lib/evma/reactor.rb +1 -1
  80. data/lib/jeventmachine.rb +7 -2
  81. data/lib/pr_eventmachine.rb +2 -2
  82. data/lib/protocols/buftok.rb +1 -1
  83. data/lib/protocols/header_and_content.rb +1 -1
  84. data/lib/protocols/httpcli2.rb +16 -6
  85. data/lib/protocols/httpclient.rb +7 -1
  86. data/lib/protocols/line_and_text.rb +6 -2
  87. data/lib/protocols/linetext2.rb +12 -14
  88. data/lib/protocols/postgres.rb +1 -1
  89. data/lib/protocols/saslauth.rb +1 -1
  90. data/lib/protocols/smtpclient.rb +1 -1
  91. data/lib/protocols/smtpserver.rb +36 -23
  92. data/lib/protocols/stomp.rb +24 -1
  93. data/lib/protocols/tcptest.rb +1 -1
  94. data/tasks/cpp.rake +77 -0
  95. data/tasks/project.rake +78 -0
  96. data/tasks/tests.rake +192 -0
  97. data/tests/test_attach.rb +1 -1
  98. data/tests/test_basic.rb +65 -12
  99. data/tests/test_defer.rb +13 -29
  100. data/tests/test_epoll.rb +16 -21
  101. data/tests/test_errors.rb +1 -1
  102. data/tests/test_eventables.rb +4 -5
  103. data/tests/test_exc.rb +1 -1
  104. data/tests/test_futures.rb +1 -1
  105. data/tests/test_hc.rb +185 -236
  106. data/tests/test_httpclient.rb +1 -1
  107. data/tests/test_httpclient2.rb +28 -6
  108. data/tests/test_kb.rb +2 -2
  109. data/tests/test_ltp.rb +139 -141
  110. data/tests/test_ltp2.rb +1 -1
  111. data/tests/test_next_tick.rb +1 -1
  112. data/tests/test_processes.rb +1 -1
  113. data/tests/test_pure.rb +3 -2
  114. data/tests/test_running.rb +1 -1
  115. data/tests/test_sasl.rb +1 -1
  116. data/tests/test_send_file.rb +56 -51
  117. data/tests/test_servers.rb +26 -36
  118. data/tests/test_smtpclient.rb +46 -44
  119. data/tests/test_smtpserver.rb +1 -1
  120. data/tests/test_spawn.rb +1 -1
  121. data/tests/test_ssl_args.rb +68 -0
  122. data/tests/test_timers.rb +15 -9
  123. data/tests/test_ud.rb +1 -1
  124. data/tests/testem.rb +30 -4
  125. metadata +69 -34
@@ -1,4 +1,4 @@
1
- # $Id: test_running.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id$
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: test_sasl.rb 720 2008-06-20 23:50:59Z francis $
1
+ # $Id$
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: test_send_file.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id$
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -37,6 +37,20 @@ class TestSendFile < Test::Unit::TestCase
37
37
  close_connection_after_writing
38
38
  end
39
39
  end
40
+
41
+ module TestClient
42
+ def data_to(&blk)
43
+ @data_to = blk
44
+ end
45
+
46
+ def receive_data(data)
47
+ @data_to.call(data) if @data_to
48
+ end
49
+
50
+ def unbind
51
+ EM.stop
52
+ end
53
+ end
40
54
 
41
55
  TestHost = "0.0.0.0"
42
56
  TestPort = 9055
@@ -54,17 +68,15 @@ class TestSendFile < Test::Unit::TestCase
54
68
  f << ("A" * 5000)
55
69
  }
56
70
 
57
- data = nil
71
+ data = ''
58
72
 
59
73
  EM.run {
60
74
  EM.start_server TestHost, TestPort, TestModule
61
75
  EM.add_timer(2) {EM.stop} # avoid hanging in case of error
62
- EM.defer proc {
63
- t = TCPSocket.new TestHost, TestPort
64
- data = t.read
65
- }, proc {
66
- EM.stop
67
- }
76
+
77
+ EM.connect TestHost, TestPort, TestClient do |c|
78
+ c.data_to { |d| data << d }
79
+ end
68
80
  }
69
81
 
70
82
  assert_equal( "A" * 5000, data )
@@ -77,18 +89,16 @@ class TestSendFile < Test::Unit::TestCase
77
89
  f << ("A" * 1000000)
78
90
  }
79
91
 
80
- data = nil
92
+ data = ''
81
93
 
82
- assert_raise(RuntimeError) {
94
+ ex_class = RUBY_PLATFORM == 'java' ? NativeException : RuntimeError
95
+ assert_raise( ex_class ) {
83
96
  EM.run {
84
97
  EM.start_server TestHost, TestPort, TestModule
85
98
  EM.add_timer(2) {EM.stop} # avoid hanging in case of error
86
- EM.defer proc {
87
- t = TCPSocket.new TestHost, TestPort
88
- data = t.read
89
- }, proc {
90
- EM.stop
91
- }
99
+ EM.connect TestHost, TestPort, TestClient do |c|
100
+ c.data_to { |d| data << d }
101
+ end
92
102
  }
93
103
  }
94
104
 
@@ -117,17 +127,14 @@ class TestSendFile < Test::Unit::TestCase
117
127
  f << ("A" * 1000)
118
128
  }
119
129
 
120
- data = nil
130
+ data = ''
121
131
 
122
132
  EM.run {
123
133
  EM.start_server TestHost, TestPort, StreamTestModule
124
134
  EM.add_timer(2) {EM.stop} # avoid hanging in case of error
125
- EM.defer proc {
126
- t = TCPSocket.new TestHost, TestPort
127
- data = t.read
128
- }, proc {
129
- EM.stop
130
- }
135
+ EM.connect TestHost, TestPort, TestClient do |c|
136
+ c.data_to { |d| data << d }
137
+ end
131
138
  }
132
139
 
133
140
  assert_equal( "A" * 1000, data )
@@ -140,17 +147,14 @@ class TestSendFile < Test::Unit::TestCase
140
147
  f << ("A" * 1000)
141
148
  }
142
149
 
143
- data = nil
150
+ data = ''
144
151
 
145
152
  EM.run {
146
153
  EM.start_server TestHost, TestPort, ChunkStreamTestModule
147
154
  EM.add_timer(2) {EM.stop} # avoid hanging in case of error
148
- EM.defer proc {
149
- t = TCPSocket.new TestHost, TestPort
150
- data = t.read
151
- }, proc {
152
- EM.stop
153
- }
155
+ EM.connect TestHost, TestPort, TestClient do |c|
156
+ c.data_to { |d| data << d }
157
+ end
154
158
  }
155
159
 
156
160
  assert_equal( "3e8\r\n#{"A" * 1000}\r\n0\r\n\r\n", data )
@@ -168,37 +172,36 @@ class TestSendFile < Test::Unit::TestCase
168
172
  end
169
173
  end
170
174
  def test_stream_bad_file
171
- data = nil
175
+ data = ''
172
176
  EM.run {
173
177
  EM.start_server TestHost, TestPort, BadFileTestModule
174
178
  EM.add_timer(2) {EM.stop} # avoid hanging in case of error
175
- EM.defer proc {
176
- t = TCPSocket.new TestHost, TestPort
177
- data = t.read
178
- }, proc {
179
- EM.stop
180
- }
179
+ EM.connect TestHost, TestPort, TestClient do |c|
180
+ c.data_to { |d| data << d }
181
+ end
181
182
  }
182
183
 
183
184
  assert_equal( "file not found", data )
184
185
  end
185
186
 
186
187
  def test_stream_large_file_data
188
+ begin
189
+ require 'fastfilereaderext'
190
+ rescue LoadError
191
+ return
192
+ end
187
193
  File.open( TestFilename, "w" ) {|f|
188
194
  f << ("A" * 10000)
189
195
  }
190
196
 
191
- data = nil
197
+ data = ''
192
198
 
193
199
  EM.run {
194
200
  EM.start_server TestHost, TestPort, StreamTestModule
195
201
  EM.add_timer(2) {EM.stop} # avoid hanging in case of error
196
- EM.defer proc {
197
- t = TCPSocket.new TestHost, TestPort
198
- data = t.read
199
- }, proc {
200
- EM.stop
201
- }
202
+ EM.connect TestHost, TestPort, TestClient do |c|
203
+ c.data_to { |d| data << d }
204
+ end
202
205
  }
203
206
 
204
207
  assert_equal( "A" * 10000, data )
@@ -207,21 +210,23 @@ class TestSendFile < Test::Unit::TestCase
207
210
  end
208
211
 
209
212
  def test_stream_large_chunked_file_data
213
+ begin
214
+ require 'fastfilereaderext'
215
+ rescue LoadError
216
+ return
217
+ end
210
218
  File.open( TestFilename, "w" ) {|f|
211
219
  f << ("A" * 100000)
212
220
  }
213
221
 
214
- data = nil
222
+ data = ''
215
223
 
216
224
  EM.run {
217
225
  EM.start_server TestHost, TestPort, ChunkStreamTestModule
218
226
  EM.add_timer(2) {EM.stop} # avoid hanging in case of error
219
- EM.defer proc {
220
- t = TCPSocket.new TestHost, TestPort
221
- data = t.read
222
- }, proc {
223
- EM.stop
224
- }
227
+ EM.connect TestHost, TestPort, TestClient do |c|
228
+ c.data_to { |d| data << d }
229
+ end
225
230
  }
226
231
 
227
232
  expected = [
@@ -1,4 +1,4 @@
1
- # $Id: test_servers.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id$
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -33,14 +33,18 @@ require 'test/unit'
33
33
  class TestServers < Test::Unit::TestCase
34
34
 
35
35
  Host = "127.0.0.1"
36
- Port = 9550
37
-
38
- def setup
39
- end
40
-
41
- def teardown
42
- end
43
-
36
+ Port = 9555
37
+
38
+ module NetstatHelper
39
+ GlobalUdp4Rexp = /udp.*\s+(?:\*|(?:0\.){3}0)[:.](\d+)\s/i
40
+ GlobalTcp4Rexp = /tcp.*\s+(?:\*|(?:0\.){3}0)[:.](\d+)\s/i
41
+ LocalUdpRexp = /udp.*\s+(?:127\.0\.0\.1|::1)[:.](\d+)\s/i
42
+ LocalTcpRexp = /tcp.*\s+(?:127\.0\.0\.1|::1)[:.](\d+)\s/i
43
+ def grep_netstat(pattern)
44
+ `netstat -an`.scan(/^.*$/).grep(pattern)
45
+ end
46
+ end
47
+ include NetstatHelper
44
48
 
45
49
  class TestStopServer < EM::Connection
46
50
  def initialize *args
@@ -51,37 +55,23 @@ class TestServers < Test::Unit::TestCase
51
55
  EM.stop_server @server_instance
52
56
  end
53
57
  end
58
+
54
59
  def run_test_stop_server
55
- succeed = false
56
- err = false
57
- EM.run {
58
- sig = EM.start_server(Host, Port)
59
- EM.defer proc {
60
- if TCPSocket.new Host, Port
61
- succeed = true
62
- end
63
- }, proc {
64
- EM.stop_server sig
65
- EM.defer proc {
66
- # Wait for the acceptor to die, otherwise
67
- # we'll probably get a conn-reset instead
68
- # of a conn-refused.
69
- sleep 0.1
70
- begin
71
- TCPSocket.new Host, Port
72
- rescue
73
- err = $!
74
- end
75
- }, proc {
76
- EM.stop
77
- }
78
- }
79
- }
80
- assert_equal( true, succeed )
81
- assert_equal( Errno::ECONNREFUSED, err.class )
60
+ EM.run {
61
+ sig = EM.start_server(Host, Port)
62
+ assert(grep_netstat(LocalTcpRexp).grep(%r(#{Port})).size >= 1, "Server didn't start")
63
+ EM.stop_server sig
64
+ # Give the server some time to shutdown.
65
+ EM.add_timer(0.1) {
66
+ assert(grep_netstat(LocalTcpRexp).grep(%r(#{Port})).empty?, "Servers didn't stop")
67
+ EM.stop
68
+ }
69
+ }
82
70
  end
83
71
  def test_stop_server
72
+ assert(grep_netstat(LocalTcpRexp).grep(Port).empty?, "Port already in use")
84
73
  5.times {run_test_stop_server}
74
+ assert(grep_netstat(LocalTcpRexp).grep(%r(#{Port})).empty?, "Servers didn't stop")
85
75
  end
86
76
 
87
77
 
@@ -1,4 +1,4 @@
1
- # $Id: test_smtpclient.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id$
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -30,52 +30,54 @@ require 'test/unit'
30
30
 
31
31
  class TestSmtpClient < Test::Unit::TestCase
32
32
 
33
- Localhost = "127.0.0.1"
34
- Localport = 9801
33
+ Localhost = "127.0.0.1"
34
+ Localport = 9801
35
35
 
36
- def setup
37
- end
36
+ def setup
37
+ end
38
38
 
39
- def teardown
40
- end
39
+ def teardown
40
+ end
41
41
 
42
- def test_a
43
- # No real tests until we have a server implementation to test against.
44
- # This is what the call looks like, though:
42
+ def test_a
43
+ # No real tests until we have a server implementation to test against.
44
+ # This is what the call looks like, though:
45
+ err = nil
46
+ EM.run {
47
+ d = EM::Protocols::SmtpClient.send :domain=>"example.com",
48
+ :host=>Localhost,
49
+ :port=>Localport, # optional, defaults 25
50
+ :starttls=>true,
51
+ :from=>"sender@example.com",
52
+ :to=> ["to_1@example.com", "to_2@example.com"],
53
+ :header=> {"Subject" => "This is a subject line"},
54
+ :body=> "This is the body of the email",
55
+ :verbose=>true
56
+ d.errback {|e|
57
+ err = e
58
+ EM.stop
59
+ }
60
+ }
61
+ assert(err)
62
+ end
45
63
 
46
- EM.run {
47
- d = EM::Protocols::SmtpClient.send :domain=>"example.com",
48
- :host=>Localhost,
49
- :port=>Localport, # optional, defaults 25
50
- :starttls=>true,
51
- :from=>"sender@example.com",
52
- :to=> ["to_1@example.com", "to_2@example.com"],
53
- :header=> {"Subject" => "This is a subject line"},
54
- :body=> "This is the body of the email",
55
- :verbose=>true
56
- d.errback {|e|
57
- p e
58
- EM.stop
59
- }
60
- }
61
- end
62
-
63
- def test_content
64
-
65
- EM.run {
66
- d = EM::Protocols::SmtpClient.send :domain=>"example.com",
67
- :host=>Localhost,
68
- :port=>Localport, # optional, defaults 25
69
- :starttls=>true,
70
- :from=>"sender@example.com",
71
- :to=> ["to_1@example.com", "to_2@example.com"],
72
- :content => ["Subject: xxx\r\n\r\ndata\r\n.\r\n"],
73
- :verbose=>true
74
- d.errback {|e|
75
- p e
76
- EM.stop
77
- }
78
- }
79
- end
64
+ def test_content
65
+ err = nil
66
+ EM.run {
67
+ d = EM::Protocols::SmtpClient.send :domain=>"example.com",
68
+ :host=>Localhost,
69
+ :port=>Localport, # optional, defaults 25
70
+ :starttls=>true,
71
+ :from=>"sender@example.com",
72
+ :to=> ["to_1@example.com", "to_2@example.com"],
73
+ :content => ["Subject: xxx\r\n\r\ndata\r\n.\r\n"],
74
+ :verbose=>true
75
+ d.errback {|e|
76
+ err = e
77
+ EM.stop
78
+ }
79
+ }
80
+ assert(err)
81
+ end
80
82
 
81
83
  end
@@ -1,4 +1,4 @@
1
- # $Id: test_smtpserver.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id$
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -1,4 +1,4 @@
1
- # $Id: test_spawn.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id$
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -0,0 +1,68 @@
1
+ require "test/unit"
2
+ require 'tempfile'
3
+
4
+ $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
5
+ require "eventmachine"
6
+
7
+ module EventMachine
8
+ def self._set_mocks
9
+ class <<self
10
+ alias set_tls_parms_old set_tls_parms
11
+ alias start_tls_old start_tls
12
+ def set_tls_parms *args; end
13
+ def start_tls *args; end
14
+ end
15
+ end
16
+
17
+ def self._clear_mocks
18
+ class <<self
19
+ alias set_tls_parms set_tls_parms_old
20
+ alias start_tls start_tls_old
21
+ end
22
+ end
23
+ end
24
+
25
+
26
+ class TestSslArgs < Test::Unit::TestCase
27
+ def setup
28
+ EventMachine._set_mocks
29
+ end
30
+
31
+ def teardown
32
+ EventMachine._clear_mocks
33
+ end
34
+
35
+ def test_tls_params_file_doesnt_exist
36
+ priv_file, cert_file = 'foo_priv_key', 'bar_cert_file'
37
+ [priv_file, cert_file].all? do |f|
38
+ assert(!File.exists?(f), "Cert file #{f} seems to exist, and should not for the tests")
39
+ end
40
+
41
+ # associate_callback_target is a pain! (build!)
42
+ conn = EventMachine::Connection.new('foo')
43
+
44
+ assert_raise(EventMachine::FileNotFoundException) do
45
+ conn.start_tls(:private_key_file => priv_file)
46
+ end
47
+ assert_raise(EventMachine::FileNotFoundException) do
48
+ conn.start_tls(:cert_chain_file => cert_file)
49
+ end
50
+ assert_raise(EventMachine::FileNotFoundException) do
51
+ conn.start_tls(:private_key_file => priv_file, :cert_chain_file => cert_file)
52
+ end
53
+ end
54
+
55
+ def test_tls_params_file_does_exist
56
+ priv_file = Tempfile.new('em_test')
57
+ cert_file = Tempfile.new('em_test')
58
+ priv_file_path = priv_file.path
59
+ cert_file_path = cert_file.path
60
+ conn = EventMachine::Connection.new('foo')
61
+ params = {:private_key_file => priv_file_path, :cert_chain_file => cert_file_path}
62
+ begin
63
+ conn.start_tls params
64
+ rescue Object
65
+ assert(false, 'should not have raised an exception')
66
+ end
67
+ end
68
+ end