empathy 0.0.1.RC0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.rdoc +135 -0
  5. data/Rakefile +33 -0
  6. data/TESTING.rdoc +11 -0
  7. data/empathy.gemspec +23 -0
  8. data/empathy.mspec +34 -0
  9. data/lib/empathy.rb +162 -0
  10. data/lib/empathy/em/condition_variable.rb +57 -0
  11. data/lib/empathy/em/mutex.rb +70 -0
  12. data/lib/empathy/em/queue.rb +84 -0
  13. data/lib/empathy/em/thread.rb +363 -0
  14. data/lib/empathy/object.rb +19 -0
  15. data/lib/empathy/thread.rb +8 -0
  16. data/lib/empathy/version.rb +3 -0
  17. data/mspec/lib/mspec/empathy.rb +19 -0
  18. data/mspec/lib/mspec/guards/empathy.rb +10 -0
  19. data/rubyspec/core/kernel/fixtures/__method__.rb +25 -0
  20. data/rubyspec/core/kernel/fixtures/autoload_b.rb +5 -0
  21. data/rubyspec/core/kernel/fixtures/autoload_c.rb +5 -0
  22. data/rubyspec/core/kernel/fixtures/autoload_d.rb +5 -0
  23. data/rubyspec/core/kernel/fixtures/caller_fixture1.rb +42 -0
  24. data/rubyspec/core/kernel/fixtures/caller_fixture2.rb +26 -0
  25. data/rubyspec/core/kernel/fixtures/chomp.rb +4 -0
  26. data/rubyspec/core/kernel/fixtures/chomp_f.rb +4 -0
  27. data/rubyspec/core/kernel/fixtures/chop.rb +4 -0
  28. data/rubyspec/core/kernel/fixtures/chop_f.rb +4 -0
  29. data/rubyspec/core/kernel/fixtures/classes.rb +410 -0
  30. data/rubyspec/core/kernel/fixtures/eval_locals.rb +6 -0
  31. data/rubyspec/core/kernel/fixtures/eval_return_with_lambda.rb +12 -0
  32. data/rubyspec/core/kernel/fixtures/eval_return_without_lambda.rb +14 -0
  33. data/rubyspec/core/kernel/fixtures/test.rb +362 -0
  34. data/rubyspec/core/kernel/sleep_spec.rb +43 -0
  35. data/rubyspec/core/mutex/lock_spec.rb +8 -0
  36. data/rubyspec/core/mutex/locked_spec.rb +8 -0
  37. data/rubyspec/core/mutex/sleep_spec.rb +56 -0
  38. data/rubyspec/core/mutex/synchronize_spec.rb +8 -0
  39. data/rubyspec/core/mutex/try_lock_spec.rb +8 -0
  40. data/rubyspec/core/mutex/unlock_spec.rb +8 -0
  41. data/rubyspec/core/thread/abort_on_exception_spec.rb +126 -0
  42. data/rubyspec/core/thread/add_trace_func_spec.rb +7 -0
  43. data/rubyspec/core/thread/alive_spec.rb +60 -0
  44. data/rubyspec/core/thread/allocate_spec.rb +9 -0
  45. data/rubyspec/core/thread/backtrace_spec.rb +7 -0
  46. data/rubyspec/core/thread/critical_spec.rb +96 -0
  47. data/rubyspec/core/thread/current_spec.rb +15 -0
  48. data/rubyspec/core/thread/element_reference_spec.rb +53 -0
  49. data/rubyspec/core/thread/element_set_spec.rb +46 -0
  50. data/rubyspec/core/thread/exclusive_spec.rb +20 -0
  51. data/rubyspec/core/thread/exit_spec.rb +21 -0
  52. data/rubyspec/core/thread/fixtures/classes.rb +291 -0
  53. data/rubyspec/core/thread/fork_spec.rb +9 -0
  54. data/rubyspec/core/thread/group_spec.rb +5 -0
  55. data/rubyspec/core/thread/initialize_spec.rb +26 -0
  56. data/rubyspec/core/thread/inspect_spec.rb +48 -0
  57. data/rubyspec/core/thread/join_spec.rb +63 -0
  58. data/rubyspec/core/thread/key_spec.rb +64 -0
  59. data/rubyspec/core/thread/keys_spec.rb +47 -0
  60. data/rubyspec/core/thread/kill_spec.rb +21 -0
  61. data/rubyspec/core/thread/list_spec.rb +38 -0
  62. data/rubyspec/core/thread/main_spec.rb +10 -0
  63. data/rubyspec/core/thread/new_spec.rb +56 -0
  64. data/rubyspec/core/thread/pass_spec.rb +8 -0
  65. data/rubyspec/core/thread/priority_spec.rb +9 -0
  66. data/rubyspec/core/thread/raise_spec.rb +225 -0
  67. data/rubyspec/core/thread/run_spec.rb +9 -0
  68. data/rubyspec/core/thread/safe_level_spec.rb +6 -0
  69. data/rubyspec/core/thread/set_trace_func_spec.rb +7 -0
  70. data/rubyspec/core/thread/shared/exit.rb +173 -0
  71. data/rubyspec/core/thread/shared/start.rb +51 -0
  72. data/rubyspec/core/thread/shared/wakeup.rb +59 -0
  73. data/rubyspec/core/thread/start_spec.rb +9 -0
  74. data/rubyspec/core/thread/status_spec.rb +48 -0
  75. data/rubyspec/core/thread/stop_spec.rb +66 -0
  76. data/rubyspec/core/thread/terminate_spec.rb +11 -0
  77. data/rubyspec/core/thread/value_spec.rb +36 -0
  78. data/rubyspec/core/thread/wakeup_spec.rb +7 -0
  79. data/rubyspec/empathy_spec.rb +26 -0
  80. data/rubyspec/library/conditionvariable/broadcast_spec.rb +62 -0
  81. data/rubyspec/library/conditionvariable/signal_spec.rb +64 -0
  82. data/rubyspec/library/conditionvariable/wait_spec.rb +21 -0
  83. data/rubyspec/library/mutex/lock_spec.rb +10 -0
  84. data/rubyspec/library/mutex/locked_spec.rb +10 -0
  85. data/rubyspec/library/mutex/synchronize_spec.rb +10 -0
  86. data/rubyspec/library/mutex/try_lock_spec.rb +10 -0
  87. data/rubyspec/library/mutex/unlock_spec.rb +10 -0
  88. data/rubyspec/library/queue/append_spec.rb +7 -0
  89. data/rubyspec/library/queue/clear_spec.rb +15 -0
  90. data/rubyspec/library/queue/deq_spec.rb +7 -0
  91. data/rubyspec/library/queue/empty_spec.rb +15 -0
  92. data/rubyspec/library/queue/enq_spec.rb +7 -0
  93. data/rubyspec/library/queue/length_spec.rb +7 -0
  94. data/rubyspec/library/queue/num_waiting_spec.rb +19 -0
  95. data/rubyspec/library/queue/pop_spec.rb +7 -0
  96. data/rubyspec/library/queue/push_spec.rb +7 -0
  97. data/rubyspec/library/queue/shared/deque.rb +37 -0
  98. data/rubyspec/library/queue/shared/enque.rb +10 -0
  99. data/rubyspec/library/queue/shared/length.rb +9 -0
  100. data/rubyspec/library/queue/shift_spec.rb +7 -0
  101. data/rubyspec/library/queue/size_spec.rb +7 -0
  102. data/rubyspec/shared/kernel/raise.rb +68 -0
  103. data/rubyspec/shared/mutex/lock.rb +52 -0
  104. data/rubyspec/shared/mutex/locked.rb +31 -0
  105. data/rubyspec/shared/mutex/synchronize.rb +23 -0
  106. data/rubyspec/shared/mutex/try_lock.rb +30 -0
  107. data/rubyspec/shared/mutex/unlock.rb +35 -0
  108. data/rubyspec/spec_helper.rb +48 -0
  109. data/spec/empathy_spec.rb +129 -0
  110. data/spec/library_spec.rb +79 -0
  111. data/spec/spec_helper.rb +6 -0
  112. metadata +222 -0
@@ -0,0 +1,19 @@
1
+
2
+ warn "empathy/object: Monkey patching Object#sleep and Object@at_exit for EM::reactor awareness"
3
+
4
+ # Monkey patch object to make EM safe
5
+ class Object
6
+
7
+ # use EM safe sleep if we are in the reactor
8
+ def sleep(*args)
9
+ kernel = Empathy.event_machine? ? Empathy::EM::Kernel : Kernel
10
+ kernel.sleep(*args)
11
+ end
12
+
13
+ # run exit blocks created in the reactor as reactor shutdown hooks
14
+ def at_exit(&block)
15
+ kernel = Empathy.event_machine? ? Empathy::EM::Kernel : Kernel
16
+ kernel.at_exit(&block)
17
+ end
18
+ end
19
+
@@ -0,0 +1,8 @@
1
+ require 'eventmachine'
2
+ require 'empathy'
3
+ require 'empathy/object'
4
+
5
+ module Empathy
6
+ map_classes(::EventMachine,::Object,"Thread","Queue","Mutex","ConditionVariable", "ThreadError" )
7
+ map_classes(::Object,Empathy::EM,"Thread","Queue","Mutex","ConditionVariable", "ThreadError" => FiberError)
8
+ end
@@ -0,0 +1,3 @@
1
+ module Empathy
2
+ VERSION = "0.0.1.RC0"
3
+ end
@@ -0,0 +1,19 @@
1
+ require 'empathy/thread'
2
+ require 'mspec'
3
+ require 'mspec/guards/empathy'
4
+ module MSpec
5
+
6
+ class << self
7
+ alias :process_orig :process
8
+
9
+ def process
10
+ # start the EventMachine, and run reactor code within a Fiber,
11
+ # when the main fiber finishes, stop the event machine
12
+ Empathy.run do
13
+ process_orig
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,10 @@
1
+ class SpecGuard
2
+ alias :implementation_orig :implementation?
3
+ def implementation?(*args)
4
+ args.any? { |name| name == :empathy } || implementation_orig(*args)
5
+ end
6
+
7
+ def standard?
8
+ implementation?(:ruby) && !implementation?(:empathy)
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ module KernelSpecs
2
+ class MethodTest
3
+ def f
4
+ __method__
5
+ end
6
+
7
+ alias_method :g, :f
8
+
9
+ def in_block
10
+ (1..2).map { __method__ }
11
+ end
12
+
13
+ define_method(:dm) do
14
+ __method__
15
+ end
16
+
17
+ define_method(:dm_block) do
18
+ (1..2).map { __method__ }
19
+ end
20
+
21
+ def from_eval
22
+ eval "__method__"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module KSAutoloadB
2
+ def self.loaded
3
+ :ksautoload_b
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module KSAutoloadC
2
+ def self.loaded
3
+ :ksautoload_c
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module KSAutoloadD
2
+ def self.loaded
3
+ :ksautoload_d
4
+ end
5
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../caller_fixture2', __FILE__)
2
+ 2 + 2
3
+ 3 + 3
4
+ CallerFixture.capture do
5
+ 5 + 5
6
+ 6 + 6
7
+ :seven
8
+ 8 + 8
9
+ end
10
+
11
+ module CallerFixture
12
+ module_function
13
+ def example_proc
14
+ Proc.new do
15
+ 1 + 1
16
+ 2 + 2
17
+ end
18
+ end
19
+
20
+ def entry_point
21
+ second
22
+ end
23
+
24
+ def second
25
+ third
26
+ end
27
+
28
+ def third
29
+ b = fourth do
30
+ 1 + 1
31
+ caller(0)
32
+ end
33
+ 2 + 2
34
+ 3 + 3
35
+ return b
36
+ end
37
+
38
+ def fourth(&block)
39
+ return block
40
+ end
41
+ end
42
+
@@ -0,0 +1,26 @@
1
+ module CallerFixture
2
+ def block
3
+ @block
4
+ end
5
+ module_function :block
6
+
7
+ def block=(block)
8
+ @block = block
9
+ end
10
+ module_function :block=
11
+
12
+ def capture(&block)
13
+ @block = block
14
+ end
15
+ module_function :capture
16
+
17
+ def caller_of(block)
18
+ eval("caller(0)", block.binding)
19
+ end
20
+ module_function :caller_of
21
+
22
+ def eval_caller(depth)
23
+ eval("caller(#{depth})")
24
+ end
25
+ module_function :eval_caller
26
+ end
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $_ = "あれ\r\n"
4
+ print Kernel.chomp
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $_ = "あれ\r\n"
4
+ print chomp
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $_ = "あれ"
4
+ print Kernel.chop
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $_ = "あれ"
4
+ print chop
@@ -0,0 +1,410 @@
1
+ require File.expand_path('../caller_fixture1', __FILE__)
2
+
3
+ module KernelSpecs
4
+ def self.Array_function(arg)
5
+ Array(arg)
6
+ end
7
+
8
+ def self.Array_method(arg)
9
+ Kernel.Array(arg)
10
+ end
11
+
12
+ def self.putc_function(arg)
13
+ putc arg
14
+ end
15
+
16
+ def self.putc_method(arg)
17
+ Kernel.putc arg
18
+ end
19
+
20
+ def self.has_private_method(name)
21
+ cmd = <<-EOC
22
+ | #{RUBY_EXE} -n -e '
23
+ m = Kernel.private_instance_methods(false).grep(/^#{name}$/)
24
+ print m.map { |x| x.to_s }.join("")
25
+ '
26
+ EOC
27
+ ruby_exe("puts", :args => cmd) == name.to_s
28
+ end
29
+
30
+ def self.chop(str, method)
31
+ cmd = "| #{RUBY_EXE} -n -e '$_ = #{str.inspect}; #{method}; print $_'"
32
+ ruby_exe "puts", :args => cmd
33
+ end
34
+
35
+ def self.encoded_chop(file)
36
+ ruby_exe "puts", :args => "| #{RUBY_EXE} -n #{file}"
37
+ end
38
+
39
+ def self.chomp(str, method, sep="\n")
40
+ cmd = "| #{RUBY_EXE} -n -e '$_ = #{str.inspect}; $/ = #{sep.inspect}; #{method}; print $_'"
41
+ ruby_exe "puts", :args => cmd
42
+ end
43
+
44
+ def self.encoded_chomp(file)
45
+ ruby_exe "puts", :args => "| #{RUBY_EXE} -n #{file}"
46
+ end
47
+
48
+ class Method
49
+ public :abort, :exec, :exit, :exit!, :fork, :system
50
+ public :spawn if respond_to?(:spawn, true)
51
+ end
52
+
53
+ class Methods
54
+
55
+ module MetaclassMethods
56
+ def peekaboo
57
+ end
58
+
59
+ protected
60
+
61
+ def nopeeking
62
+ end
63
+
64
+ private
65
+
66
+ def shoo
67
+ end
68
+ end
69
+
70
+ def self.ichi; end
71
+ def ni; end
72
+ class << self
73
+ def san; end
74
+ end
75
+
76
+ private
77
+
78
+ def self.shi; end
79
+ def juu_shi; end
80
+
81
+ class << self
82
+ def roku; end
83
+
84
+ private
85
+
86
+ def shichi; end
87
+ end
88
+
89
+ protected
90
+
91
+ def self.hachi; end
92
+ def ku; end
93
+
94
+ class << self
95
+ def juu; end
96
+
97
+ protected
98
+
99
+ def juu_ichi; end
100
+ end
101
+
102
+ public
103
+
104
+ def self.juu_ni; end
105
+ def juu_san; end
106
+ end
107
+
108
+ class PrivateSup
109
+ def public_in_sub
110
+ end
111
+
112
+ private :public_in_sub
113
+ end
114
+
115
+ class PublicSub < PrivateSup
116
+ def public_in_sub
117
+ end
118
+ end
119
+
120
+ class A
121
+ # 1.9 as Kernel#public_method, so we don't want this one to clash:
122
+ def pub_method; :public_method; end
123
+
124
+ def undefed_method; :undefed_method; end
125
+ undef_method :undefed_method
126
+
127
+ protected
128
+ def protected_method; :protected_method; end
129
+
130
+ private
131
+ def private_method; :private_method; end
132
+
133
+ public
134
+ define_method(:defined_method) { :defined }
135
+ end
136
+
137
+ class B < A
138
+ alias aliased_pub_method pub_method
139
+ end
140
+
141
+ class VisibilityChange
142
+ class << self
143
+ private :new
144
+ end
145
+ end
146
+
147
+ class Binding
148
+ @@super_secret = "password"
149
+
150
+ def initialize(n)
151
+ @secret = n
152
+ end
153
+
154
+ def square(n)
155
+ n * n
156
+ end
157
+
158
+ def get_binding
159
+ a = true
160
+ @bind = binding
161
+
162
+ # Add/Change stuff
163
+ b = true
164
+ @secret += 1
165
+
166
+ @bind
167
+ end
168
+ end
169
+
170
+
171
+ module BlockGiven
172
+ def self.accept_block
173
+ block_given?
174
+ end
175
+
176
+ def self.accept_block_as_argument(&block)
177
+ block_given?
178
+ end
179
+
180
+ class << self
181
+ define_method(:defined_block) do
182
+ block_given?
183
+ end
184
+ end
185
+ end
186
+
187
+ module KernelBlockGiven
188
+ def self.accept_block
189
+ Kernel.block_given?
190
+ end
191
+
192
+ def self.accept_block_as_argument(&block)
193
+ Kernel.block_given?
194
+ end
195
+
196
+ class << self
197
+ define_method(:defined_block) do
198
+ Kernel.block_given?
199
+ end
200
+ end
201
+ end
202
+
203
+ module SelfBlockGiven
204
+ def self.accept_block
205
+ self.send(:block_given?)
206
+ end
207
+
208
+ def self.accept_block_as_argument(&block)
209
+ self.send(:block_given?)
210
+ end
211
+
212
+ class << self
213
+ define_method(:defined_block) do
214
+ self.send(:block_given?)
215
+ end
216
+ end
217
+ end
218
+
219
+ module KernelBlockGiven
220
+ def self.accept_block
221
+ Kernel.block_given?
222
+ end
223
+
224
+ def self.accept_block_as_argument(&block)
225
+ Kernel.block_given?
226
+ end
227
+
228
+ class << self
229
+ define_method(:defined_block) do
230
+ Kernel.block_given?
231
+ end
232
+ end
233
+ end
234
+
235
+ class IVars
236
+ def initialize
237
+ @secret = 99
238
+ end
239
+ end
240
+
241
+ module InstEvalCVar
242
+ instance_eval { @@count = 2 }
243
+ end
244
+
245
+ module InstEval
246
+ def self.included(base)
247
+ base.instance_eval { @@count = 2 }
248
+ end
249
+ end
250
+
251
+ class IncludesInstEval
252
+ include InstEval
253
+ end
254
+
255
+ class InstEvalConst
256
+ INST_EVAL_CONST_X = 2
257
+ end
258
+
259
+ module InstEvalOuter
260
+ module Inner
261
+ obj = InstEvalConst.new
262
+ X_BY_STR = obj.instance_eval("INST_EVAL_CONST_X") rescue nil
263
+ X_BY_BLOCK = obj.instance_eval { INST_EVAL_CONST_X } rescue nil
264
+ end
265
+ end
266
+
267
+ class EvalTest
268
+ def self.eval_yield_with_binding
269
+ eval("yield", binding)
270
+ end
271
+ def self.call_yield
272
+ yield
273
+ end
274
+ end
275
+
276
+ module DuplicateM
277
+ def repr
278
+ self.class.name.to_s
279
+ end
280
+ end
281
+
282
+ class Duplicate
283
+ attr_accessor :one, :two
284
+
285
+ def initialize(one, two)
286
+ @one = one
287
+ @two = two
288
+ end
289
+
290
+ def initialize_copy(other)
291
+ ScratchPad.record object_id
292
+ end
293
+ end
294
+
295
+ class Clone
296
+ def initialize_clone(other)
297
+ ScratchPad.record other.object_id
298
+ end
299
+ end
300
+
301
+ class Dup
302
+ def initialize_dup(other)
303
+ ScratchPad.record other.object_id
304
+ end
305
+ end
306
+
307
+ module ParentMixin
308
+ def parent_mixin_method; end
309
+ end
310
+
311
+ class Parent
312
+ include ParentMixin
313
+ def parent_method; end
314
+ def another_parent_method; end
315
+ def self.parent_class_method; :foo; end
316
+ end
317
+
318
+ class Child < Parent
319
+ # In case this trips anybody up: This fixtures file must only be loaded
320
+ # once for the Kernel specs. If it's loaded multiple times the following
321
+ # line raises a NameError. This is a problem if you require it from a
322
+ # location outside of core/kernel on 1.8.6, because 1.8.6 doesn't
323
+ # normalise paths...
324
+ undef_method :parent_method
325
+ end
326
+
327
+ class Grandchild < Child
328
+ undef_method :parent_mixin_method
329
+ end
330
+
331
+ # for testing lambda
332
+ class Lambda
333
+ def outer(meth)
334
+ inner(meth)
335
+ end
336
+
337
+ def mp(&b); b; end
338
+
339
+ def inner(meth)
340
+ b = mp { return :good }
341
+
342
+ pr = send(meth) { |x| x.call }
343
+
344
+ pr.call(b)
345
+
346
+ # We shouldn't be here, b should have unwinded through
347
+ return :bad
348
+ end
349
+ end
350
+
351
+ class RespondViaMissing
352
+ def respond_to_missing?(method, priv=false)
353
+ case method
354
+ when :handled_publicly
355
+ true
356
+ when :handled_privately
357
+ priv
358
+ when :not_handled
359
+ false
360
+ else
361
+ raise "Typo in method name"
362
+ end
363
+ end
364
+
365
+ def method_missing(method, *args)
366
+ "Done #{method}(#{args})"
367
+ end
368
+ end
369
+
370
+ class InstanceVariable
371
+ def initialize
372
+ @greeting = "hello"
373
+ end
374
+ end
375
+ end
376
+
377
+ class EvalSpecs
378
+ class A
379
+ eval "class B; end"
380
+ def c
381
+ eval "class C; end"
382
+ end
383
+ end
384
+
385
+ def f
386
+ yield
387
+ end
388
+
389
+ def self.call_eval
390
+ f = __FILE__
391
+ eval "true", binding, "(eval)", 1
392
+ return f
393
+ end
394
+ end
395
+
396
+ module CallerSpecs
397
+ def self.recurse(n)
398
+ return caller if n <= 0
399
+ recurse(n-1)
400
+ end
401
+ end
402
+
403
+ # for Kernel#sleep to have Channel in it's specs
404
+ # TODO: switch directly to queue for both Kernel#sleep and Thread specs?
405
+ unless defined? Channel
406
+ require 'thread'
407
+ class Channel < Queue
408
+ alias receive shift
409
+ end
410
+ end