README.textile in evented-spec-0.4.0 vs README.textile in evented-spec-0.4.1
- old
+ new
@@ -2,11 +2,11 @@
Evented-spec is a set of helpers to help you test your asynchronous code.
EventMachine/Cool.io-based code, including asynchronous "AMQP library":https://github.com/ruby-amqp/ruby-amqp is notoriously difficult to test. To the point that many people recommend using either "mocks":https://github.com/danielsdeleo/moqueue or "synchronous libraries":https://github.com/ruby-amqp/bunny instead of EM-based libraries in unit tests. This is not always an option, however -- sometimes your code just has to run inside the event loop, and you want to test a real thing, not just mocks.
-"em-spec":https://github.com/tmm1/em-spec gem made it easier to write evented specs, but it has several drawbacks. First, it is not easy to manage both EM.run and AMQP.start loops at the same time. Second, AMQP is not properly stopped and deactivated upon exceptions and timeouts, resulting in state leak between examples and multiple mystereous failures. amqp-spec, and, subsequently, evented-spec add more helpers to keep your specs from being bloated.
+"em-spec":https://github.com/tmm1/em-spec gem made it easier to write evented specs, but it had several drawbacks. First, it is not easy to manage both EM.run and AMQP.start loops at the same time. Second, AMQP is not properly stopped and deactivated upon exceptions and timeouts, resulting in state leak between examples and multiple mystereous failures. amqp-spec, and, subsequently, evented-spec add more helpers to keep your specs from being bloated.
h2. Usage
To get started with evented-spec you need to include one of the helper modules in your example groups, e.g.:
@@ -45,11 +45,11 @@
@coolio@ stands for cool.io. It takes a block, which is run after reactor starts.
All three accept a hash of options. Look into method documentation to learn more.
-h3. EventedSpec::EMSpec, EventedSpec::AMQPSpec
+h3. EventedSpec::EMSpec, EventedSpec::AMQPSpec, EventedSpec::CoolioSpec
@EventedSpec::EMSpec@ wraps every example in em block, so it might save you a couple of lines per example. @EventedSpec::AMQPSpec@ wraps every example in amqp block.
Also note that every example group including @EMSpec@ or @AMQPSpec@ automatically includes @SpecHelper@.
@@ -81,21 +81,25 @@
end
h2. Hooks
-There are 4 hooks available to evented specs:
+There are 6 hooks available to evented specs:
* @em_before@ -- launches after reactor started, before example runs
* @em_after@ -- launches right before reactor is stopped, after example runs
* @amqp_before@ -- launches after amqp connects, before example runs
* @amqp_after@ -- launches before amqp disconnects, after example runs
+* @coolio_before@ -- launches after Cool.io starts, before example runs
+* @coolio_after@ -- launches before Cool.io stops, after example runs
-So, the order of hooks is as follows: @before(:all)@, @before(:each)@,
+So, the order of hooks for an AMQP spec is as follows: @before(:all)@, @before(:each)@,
@em_before@, @amqp_before@, example, @amqp_after@, @em_after@, @after(:each)@,
@after(:all)@
+
+
bc. describe "using amqp hooks" do
include EventedSpec::AMQPSpec
default_timeout 0.5
amqp_before do
AMQP.connection.should_not be_nil
@@ -115,14 +119,10 @@
end
end
end
end
-h2. AMQP gem compatibility
-
-AMQP spec helpers are for newer version of AMQP gem, 0.8. If you need spec-helpers for AMQP gem 0.7, take a look at "amqp-spec":https://github.com/ruby-amqp/amqp-spec, API is mostly the same.
-
h2. Words of warning on blocking the reactor
Evented specs are currently run inside of reactor thread. What this effectively means is that you *should not block* during spec execution.
For example, the following *will not* work:
@@ -147,16 +147,58 @@
done
end
end
end
+You can also use #delayed helper method to maintain order of execution when callbacks are not an option.
+
+bc. describe "using amqp" do
+ include EventedSpec::AMQPSpec
+ it "should do something useful" do
+ channel = AMQP::Channel.new
+ @stage = 0
+ delayed(0.2) {
+ channel.should be_open
+ @stage = 1
+ }
+ delayed(0.3) {
+ @stage.should == 1
+ done
+ }
+ delayed(0.4) {
+ # this block is never going to be executed
+ raise "Help me!"
+ }
+ end
+end
+
+
+h2. I have an existing reactor running in separate thread, amqp specs won't work for me what should I do?
+
+Unfortunately, right now there aren't many remedies to your problem, besides stopping the event loop in before(:all) hook like this:
+
+bc. describe "Example" do
+ before(:all) { EM.stop_event_loop; sleep(0.1) }
+ after(:all) { do_something_to_restart_the_eventmachine }
+ include EventedSpec::SpecHelper
+ it "should do something" do
+ em { done }
+ end
+end
+
+Reason is simple: if we don't restart event loop every spec example, all kinds of state leaks may occur: stale timers, delayed exceptions, weirdest errors and even segfaults. It isn't impossible but it certainly is very invasive.
+
+h2. Compatibility
+
+EventedSpec is tested with RSpec >= 2.5.0, Cool.io ~> 1.0.0, EventMachine >= 0.12.10, and AMQP >= 0.8.0. Running it with RSpec 1.3 and/or AMQP 0.7.0 is not unheard of, although not tested in all its entirety.
+
h2. See also
You can see evented-spec in use in spec suites for our amqp gems, "amq-client":https://github.com/ruby-amqp/amq-client/tree/master/spec and "amqp":https://github.com/ruby-amqp/amqp/tree/master/spec.
h2. Links
* "cool.io":http://coolio.github.com/
* "amqp-spec":https://github.com/ruby-amqp/amqp-spec
* "eventmachine":http://eventmachine.rubyforge.org/
* "amqp":https://github.com/ruby-amqp/amqp
-* "amq-client":https://github.com/ruby-amqp/amq-client
\ No newline at end of file
+* "amq-client":https://github.com/ruby-amqp/amq-client