Skip to content

Commit

Permalink
Improve i/o handling in keypress listener (#21)
Browse files Browse the repository at this point in the history
- If something goes wrong when listing for key presses, make sure the
  exception gets reported. This was hiding legitimate errors.
- Don't attempt to use `IO#raw` if the input is not a TTY.
- If there aren't any characters left in stdin (as is the case when unit
  testing with `StringIO`), exit the listener loop. This speeds up unit
  tests dramatically.
  • Loading branch information
mattbrictson authored Feb 27, 2024
1 parent 1e58cbd commit 78824c5
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 7 deletions.
2 changes: 1 addition & 1 deletion lib/mighty_test/console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def clear
end

def wait_for_keypress
return stdin.getc unless stdin.respond_to?(:raw)
return stdin.getc unless stdin.respond_to?(:raw) && tty?

stdin.raw(intr: true) { stdin.getc }
end
Expand Down
7 changes: 4 additions & 3 deletions lib/mighty_test/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ def start_keypress_listener
@keypress_listener = Thread.new do
loop do
key = console.wait_for_keypress
post_event(:keypress, key) if key
rescue Interrupt
retry
break if key.nil?

post_event(:keypress, key)
end
end
@keypress_listener.abort_on_exception = true
end

def loop_for(iterations, &)
Expand Down
5 changes: 3 additions & 2 deletions test/integration/mt_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ def test_mt_runs_no_tests_if_line_number_doesnt_match
refute_match(/FailingTest/, result.stdout)
end

def test_mt_runs_watch_mode_that_executes_tests_when_files_change
def test_mt_runs_watch_mode_that_executes_tests_when_files_change # rubocop:disable Minitest/MultipleAssertions
project_dir = fixtures_path.join("example_project")
stdout, = capture_subprocess_io do
stdout, stderr = capture_subprocess_io do
# Start mt --watch in the background
pid = spawn(*%w[bundle exec mt --watch --verbose], chdir: project_dir)

Expand All @@ -75,6 +75,7 @@ def test_mt_runs_watch_mode_that_executes_tests_when_files_change
end

assert_includes(stdout, "Watching for changes to source and test files.")
assert_empty(stderr)
assert_match(/ExampleTest/, stdout)
assert_match(/\d runs, \d assertions, 0 failures, 0 errors/, stdout)
end
Expand Down
2 changes: 1 addition & 1 deletion test/mighty_test/watcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def paused?

def run_watcher(iterations: :indefinitely, in: ".", extra_args: [], stdin: nil, file_system: FileSystem.new)
listen_thread = @listen_thread
console = Console.new(stdin: stdin.nil? ? StringIO.new("") : StringIO.new(stdin))
console = Console.new(stdin: stdin.nil? ? StringIO.new : StringIO.new(stdin))
console.define_singleton_method(:clear) { puts "[CLEAR]" }
console.define_singleton_method(:play_sound) { |sound| puts "[SOUND] #{sound.inspect}" }
file_system.define_singleton_method(:listen) { |&callback| Listener.new(listen_thread, callback) }
Expand Down

0 comments on commit 78824c5

Please sign in to comment.