Permalink
Browse files

Adding a synchronous EM::Synchrony.gets to emulate gets

  • Loading branch information...
1 parent 4224adb commit 8838d0111cf3ed12da51c5fc9c5268a8c0318086 @vishnugopal vishnugopal committed Aug 19, 2011
Showing with 98 additions and 0 deletions.
  1. +6 −0 lib/em-synchrony.rb
  2. +33 −0 lib/em-synchrony/keyboard.rb
  3. +59 −0 spec/keyboard_spec.rb
View
@@ -12,6 +12,7 @@
require "em-synchrony/em-multi"
require "em-synchrony/tcpsocket"
require "em-synchrony/connection_pool"
+require "em-synchrony/keyboard"
require "em-synchrony/iterator" if EventMachine::VERSION > '0.12.10'
module EventMachine
@@ -75,5 +76,10 @@ def self.add_periodic_timer(interval, &blk)
Fiber.new { blk.call }.resume
end
end
+
+ # routes to EM::Synchrony::Keyboard
+ def self.gets
+ EventMachine::Synchrony::Keyboard.new.gets
+ end
end
end
@@ -0,0 +1,33 @@
+module EventMachine
+ module Synchrony
+ class Keyboard
+ attr_reader :current_fiber, :separator
+
+ def gets
+ @current_fiber = Fiber.current
+ EM.open_keyboard(EventMachine::Synchrony::KeyboardHandler, self)
+
+ Fiber.yield
+ end
+ end
+
+ class KeyboardHandler < EM::Connection
+ include EM::Protocols::LineText2
+
+ def initialize(keyboard)
+ @keyboard = keyboard
+ end
+
+ def receive_line(line)
+ # Simulate gets by adding a trailing line feed
+ @input = "#{line}#{$/}"
+
+ close_connection
+ end
+
+ def unbind
+ @keyboard.current_fiber.resume @input
+ end
+ end
+ end
+end
View
@@ -0,0 +1,59 @@
+require "spec/helper/all"
+require "tempfile"
+
+DELAY = 0.1
+
+describe EventMachine::Synchrony do
+ before(:each) { @temp_file = Tempfile.new("stdout") }
+ after(:each) { @temp_file.unlink }
+
+ def with_input(string = "", &block)
+ string = "#{string}\n"
+
+ @temp_file.write string
+ @temp_file.flush
+
+ EM::Synchrony.add_timer(DELAY) do
+ original_stdin = STDIN
+ STDIN.reopen(@temp_file.path)
+
+ block.call if block_given?
+
+ STDIN.reopen(original_stdin)
+ end
+ end
+
+ it "waits for input" do
+ EM.synchrony do
+ start = now
+
+ with_input do
+ EM::Synchrony.gets
+
+ (now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
+ end
+
+ EM.add_timer(DELAY * 2) { EM.stop }
+ end
+ end
+
+ it "trails input with a newline to emulate gets" do
+ EM.synchrony do
+ with_input("Hello") do
+ EM::Synchrony.gets.should == "Hello\n"
+ end
+
+ EM.add_timer(DELAY * 2) { EM.stop }
+ end
+ end
+
+ it "should stop after the first line" do
+ EM.synchrony do
+ with_input("Hello\nWorld!") do
+ EM::Synchrony.gets.should == "Hello\n"
+ end
+
+ EM.add_timer(DELAY * 2) { EM.stop }
+ end
+ end
+end

0 comments on commit 8838d01

Please sign in to comment.