tmm1-em-spec 0.1.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/README +40 -0
- data/lib/em/spec.rb +58 -0
- data/lib/ext/em.rb +37 -0
- data/lib/ext/fiber18.rb +70 -0
- metadata +64 -0
data/README
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Simple BDD API for testing asynchronous Ruby/EventMachine code
|
2
|
+
(c) 2008 Aman Gupta (tmm1)
|
3
|
+
|
4
|
+
|
5
|
+
The API is identical to Bacon, except that you must explicitly call 'done' after all the current behavior's assertions have been made:
|
6
|
+
|
7
|
+
require 'em/spec'
|
8
|
+
|
9
|
+
EM.describe EventMachine do
|
10
|
+
|
11
|
+
should 'have timers' do
|
12
|
+
start = Time.now
|
13
|
+
|
14
|
+
EM.add_timer(0.5){
|
15
|
+
(Time.now-start).should.be.close 0.5, 0.1
|
16
|
+
done
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'have periodic timers' do
|
21
|
+
num = 0
|
22
|
+
start = Time.now
|
23
|
+
|
24
|
+
timer = EM.add_periodic_timer(0.5){
|
25
|
+
if (num += 1) == 2
|
26
|
+
(Time.now-start).should.be.close 1.0, 0.1
|
27
|
+
EM.__send__ :cancel_timer, timer
|
28
|
+
done
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
Resources:
|
37
|
+
|
38
|
+
Git repository: http://github.com/tmm1/em-spec
|
39
|
+
Bacon: http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/30b07b651b0662fd
|
40
|
+
Initial announcement: http://groups.google.com/group/eventmachine/browse_thread/thread/8b4e7ead72f9d013
|
data/lib/em/spec.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../ext/fiber18'
|
2
|
+
|
3
|
+
require 'bacon'
|
4
|
+
|
5
|
+
class Bacon::Context
|
6
|
+
unless method_defined? :_it
|
7
|
+
alias :_it :it
|
8
|
+
def it *args
|
9
|
+
_it(*args){ if block_given? then yield; Fiber.yield end }
|
10
|
+
end
|
11
|
+
def done() $bacon_fiber.resume if $bacon_fiber end
|
12
|
+
alias :resume :done
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'eventmachine'
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
def self.spec *args, &blk
|
20
|
+
raise ArgumentError, 'block required' unless block_given?
|
21
|
+
raise 'EventMachine reactor already running' if EM.reactor_running?
|
22
|
+
|
23
|
+
EM.run{
|
24
|
+
Bacon.summary_on_exit
|
25
|
+
($bacon_fiber = Fiber.new{
|
26
|
+
Bacon::Context.new(args.join(' '), &blk)
|
27
|
+
EM.stop_event_loop
|
28
|
+
}).resume
|
29
|
+
}
|
30
|
+
end
|
31
|
+
class << self; alias :describe :spec; end
|
32
|
+
end
|
33
|
+
|
34
|
+
EM.describe EventMachine do
|
35
|
+
|
36
|
+
should 'have timers' do
|
37
|
+
start = Time.now
|
38
|
+
|
39
|
+
EM.add_timer(0.5){
|
40
|
+
(Time.now-start).should.be.close 0.5, 0.1
|
41
|
+
done
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
should 'have periodic timers' do
|
46
|
+
num = 0
|
47
|
+
start = Time.now
|
48
|
+
|
49
|
+
timer = EM.add_periodic_timer(0.5){
|
50
|
+
if (num += 1) == 2
|
51
|
+
(Time.now-start).should.be.close 1.0, 0.1
|
52
|
+
EM.__send__ :cancel_timer, timer
|
53
|
+
done
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
end if __FILE__ == $0
|
data/lib/ext/em.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'eventmachine'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require 'eventmachine'
|
6
|
+
end
|
7
|
+
|
8
|
+
# copied from EM trunk, will be removed when 0.12.1 is released
|
9
|
+
if EM::VERSION < '0.12.1'
|
10
|
+
|
11
|
+
def EventMachine::run blk=nil, tail=nil, &block
|
12
|
+
@tails ||= []
|
13
|
+
tail and @tails.unshift(tail)
|
14
|
+
|
15
|
+
if reactor_running?
|
16
|
+
(b = blk || block) and b.call # next_tick(b)
|
17
|
+
else
|
18
|
+
@conns = {}
|
19
|
+
@acceptors = {}
|
20
|
+
@timers = {}
|
21
|
+
begin
|
22
|
+
@reactor_running = true
|
23
|
+
initialize_event_machine
|
24
|
+
(b = blk || block) and add_timer(0, b)
|
25
|
+
run_machine
|
26
|
+
ensure
|
27
|
+
release_machine
|
28
|
+
@reactor_running = false
|
29
|
+
end
|
30
|
+
|
31
|
+
until @tails.empty?
|
32
|
+
@tails.pop.call
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/lib/ext/fiber18.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Poor Man's Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)
|
2
|
+
# (c) 2008 Aman Gupta (tmm1)
|
3
|
+
|
4
|
+
unless defined? Fiber
|
5
|
+
require 'thread'
|
6
|
+
|
7
|
+
class FiberError < StandardError; end
|
8
|
+
|
9
|
+
class Fiber
|
10
|
+
def initialize
|
11
|
+
raise ArgumentError, 'new Fiber requires a block' unless block_given?
|
12
|
+
|
13
|
+
@yield = Queue.new
|
14
|
+
@resume = Queue.new
|
15
|
+
|
16
|
+
@thread = Thread.new{ @yield.push [ *yield(*@resume.pop) ] }
|
17
|
+
@thread.abort_on_exception = true
|
18
|
+
@thread[:fiber] = self
|
19
|
+
end
|
20
|
+
attr_reader :thread
|
21
|
+
|
22
|
+
def resume *args
|
23
|
+
raise FiberError, 'dead fiber called' unless @thread.alive?
|
24
|
+
@resume.push(args)
|
25
|
+
result = @yield.pop
|
26
|
+
result.size > 1 ? result : result.first
|
27
|
+
end
|
28
|
+
|
29
|
+
def yield *args
|
30
|
+
@yield.push(args)
|
31
|
+
result = @resume.pop
|
32
|
+
result.size > 1 ? result : result.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.yield *args
|
36
|
+
raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
|
37
|
+
fiber.yield(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.current
|
41
|
+
Thread.current[:fiber] or raise FiberError, 'not inside a fiber'
|
42
|
+
end
|
43
|
+
|
44
|
+
def inspect
|
45
|
+
"#<#{self.class}:0x#{self.object_id.to_s(16)}>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if __FILE__ == $0
|
51
|
+
f = Fiber.new{ puts 'hi'; p Fiber.yield(1); puts 'bye'; :done }
|
52
|
+
p f.resume
|
53
|
+
p f.resume(2)
|
54
|
+
end
|
55
|
+
|
56
|
+
__END__
|
57
|
+
|
58
|
+
$ ruby fbr.rb
|
59
|
+
hi
|
60
|
+
1
|
61
|
+
2
|
62
|
+
bye
|
63
|
+
:done
|
64
|
+
|
65
|
+
$ ruby1.9 fbr.rb
|
66
|
+
hi
|
67
|
+
1
|
68
|
+
2
|
69
|
+
bye
|
70
|
+
:done
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tmm1-em-spec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aman Gupta
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-01 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: eventmachine
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.12.0
|
23
|
+
version:
|
24
|
+
description: Bacon based BDD API for Ruby/EventMachine
|
25
|
+
email: em-spec@tmm1.net
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- lib/em/spec.rb
|
35
|
+
- lib/ext/em.rb
|
36
|
+
- lib/ext/fiber18.rb
|
37
|
+
has_rdoc: false
|
38
|
+
homepage: http://github.com/tmm1/em-spec
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.2.0
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: Bacon based BDD API for Ruby/EventMachine
|
63
|
+
test_files: []
|
64
|
+
|