diff --git a/lib/yamatanooroti/windows.rb b/lib/yamatanooroti/windows.rb index 7cc7343..d4231be 100644 --- a/lib/yamatanooroti/windows.rb +++ b/lib/yamatanooroti/windows.rb @@ -519,42 +519,70 @@ def result @result || retrieve_screen end + private def assert_screen_with_proc(check_proc, assert_block, convert_proc = :itself.to_proc) + retry_until = Time.now + @timeout + while Time.now < retry_until + #break unless try_sync + + break if check_proc.call(convert_proc.call(result)) + sleep @wait + end + sleep @wait + assert_block.call(convert_proc.call(result)) + end + def assert_screen(expected_lines, message = nil) - actual_lines = result - actual_string = actual_lines.join("\n").sub(/\n*\z/, "\n") + lines_to_string = ->(lines) { lines.join("\n").sub(/\n*\z/, "\n") } case expected_lines when Array - assert_equal(expected_lines, actual_lines, message) + assert_screen_with_proc( + ->(a) { expected_lines == a }, + ->(a) { assert_equal(expected_lines, a, message) } + ) when String - assert_equal(expected_lines, actual_string, message) + assert_screen_with_proc( + ->(a) { expected_lines == a }, + ->(a) { assert_equal(expected_lines, a, message) }, + lines_to_string + ) when Regexp - assert_match(expected_lines, actual_string, message) + assert_screen_with_proc( + ->(a) { expected_lines.match?(a) }, + ->(a) { assert_match(expected_lines, a, message) }, + lines_to_string + ) end end - def start_terminal(height, width, command, wait: 1, startup_message: nil) - @height = height - @width = width + def start_terminal(height, width, command, wait: 0.2, timeout: 2, startup_message: nil) + @timeout = timeout @wait = wait @result = nil + + @height = height + @width = width setup_console(height, width) launch(command.map{ |c| quote_command_arg(c) }.join(' ')) + case startup_message when String - check_startup_message = ->(message) { - message.start_with?( - startup_message.each_char.each_slice(width).map(&:join).join("\0").gsub(/ *\0/, "\n") - ) - } + wait_startup_message { |message| message.start_with?(startup_message) } when Regexp - check_startup_message = ->(message) { startup_message.match?(message) } + wait_startup_message { |message| startup_message.match?(message) } end - if check_startup_message - loop do - screen = retrieve_screen.join("\n").sub(/\n*\z/, "\n") - break if check_startup_message.(screen) - sleep @wait + end + + private def wait_startup_message + wait_until = Time.now + @timeout + chunks = +'' + loop do + wait = wait_until - Time.now + if wait.negative? + raise "Startup message didn't arrive within timeout: #{chunks.inspect}" end + + chunks = retrieve_screen.join("\n").sub(/\n*\z/, "\n") + break if yield chunks end end end