Commit 434d647

mokha <mokha@cisco.com>
2019-04-15 22:35:56
add logical waits for #emails and #open
1 parent bc4e620
Changed files (2)
lib
minbox
spec
lib/minbox/inbox.rb
@@ -5,7 +5,10 @@ module Minbox
     include Singleton
     include Enumerable
 
-    def initialize(root_dir: 'tmp')
+    attr_accessor :seconds
+
+    def initialize(root_dir: 'tmp', seconds: 1)
+      @seconds = seconds
       empty!
       ::Listen.to(File.expand_path(root_dir), only: /\.eml$/) do |modified, added, removed|
         added.each do |file|
@@ -14,21 +17,27 @@ module Minbox
       end.start
     end
 
-    def emails
+    def emails(count: 0)
+      wait_until { |x| x.count >= count } if count > 0
+
       @emails.keys
     end
 
-    def until(seconds: 10, wait: 0.1)
+    def wait_until(seconds: self.seconds, wait: 0.1)
       iterations = (seconds / wait).to_i
       iterations.times do
-        return if yield(self)
-
+        return true if yield(self)
         sleep wait
       end
-      raise "timeout: #{seconds} seconds elapsed."
+      false
+    end
+
+    def wait_until!(*args, &block)
+      raise "timeout: expired. #{args}" unless wait_until(*args, &block)
     end
 
     def open(id)
+      wait_until { @emails[id] }
       @emails[id]
     end
 
spec/minbox/inbox_spec.rb
@@ -36,28 +36,29 @@ RSpec.describe Minbox::Inbox do
   end
 
   describe "#emails" do
-    before do
-      create_emails
-      subject.until { |inbox| inbox.count == 2 }
-    end
+    before { create_emails }
 
-    specify { expect(subject.emails).to match_array(['1.eml', '2.eml']) }
+    specify { expect(subject.emails(count: 2)).to match_array(['1.eml', '2.eml']) }
   end
 
-  describe "#until" do
-    before do
-      create_emails
-      subject.until { |inbox| inbox.count == 2 }
+  describe "#wait_until!" do
+    context "when the condition is satisfied" do
+      before { create_emails }
+
+      specify { expect(subject.emails(count: 2)).to match_array(['1.eml', '2.eml']) }
     end
 
-    specify { expect(subject.emails).to match_array(['1.eml', '2.eml']) }
+    context "when the condition is not satisfied" do
+      specify do
+        expect do
+          subject.wait_until!(seconds: 0.1) { |inbox| false }
+        end.to raise_error(/timeout/)
+      end
+    end
   end
 
   describe "#open" do
-    before do
-      create_emails
-      subject.until { |inbox| inbox.count == 2 }
-    end
+    before { create_emails }
 
     context "when opening an email in the inbox" do
       let(:result) { subject.open('2.eml') }