I''ve been experimenting with different techniques for testing async
code, and have a simple Bacon based BDD api working:
EM.describe EventMachine do
should ''have timers'' do
start = Time.now
EM.add_timer(0.5){
(Time.now-start).should.be.close 0.5, 0.1
done
}
end
should ''have periodic timers'' do
num = 0
start = Time.now
ptimer = EM.add_periodic_timer(0.5){
if (num += 1) == 2
(Time.now-start).should.be.close 1.0, 0.1
EM.cancel_timer ptimer
done
end
}
end
end
To move onto the next ''should'' requirement in the spec, you
must
explicitly call ''done'' (or ''resume''). This
means each ''should'' will
effectively wait until all callbacks have been triggered and
associated assertions have been made, making it much easier to test
asynchronous code.
To achieve this, EM.describe wraps the block in a Fiber (with a simple
Thread based compatibility layer for Fibers on 1.8:
http://gist.github.com/4631),
and calls Fiber.yield at the end of each ''should''. When you
call
''done'', it simply resumes the Fiber and continues on to the
next
requirement.
The full code is available at http://gist.github.com/4708
Aman