89 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require "delegate"
 | |
| 
 | |
| module Test
 | |
|   module Helper
 | |
|     module OutputAsTTY
 | |
|       # This is a custom wrapper for the `output` matcher,
 | |
|       # used for testing output to a TTY:
 | |
|       #
 | |
|       #   expect {
 | |
|       #     print "test" if $stdout.tty?
 | |
|       #   }.to output("test").to_stdout.as_tty
 | |
|       #
 | |
|       #   expect {
 | |
|       #     # command
 | |
|       #   }.to output(...).to_stderr.as_tty.with_color
 | |
|       #
 | |
|       class Output < SimpleDelegator
 | |
|         def matches?(block)
 | |
|           return super(block) unless @tty
 | |
| 
 | |
|           colored_tty_block = lambda do
 | |
|             instance_eval("$#{@output}  # $stdout", __FILE__, __LINE__).extend(Module.new do
 | |
|               def tty?
 | |
|                 true
 | |
|               end
 | |
| 
 | |
|               alias_method :isatty, :tty?
 | |
|             end)
 | |
|             block.call
 | |
|           end
 | |
| 
 | |
|           return super(colored_tty_block) if @colors
 | |
| 
 | |
|           uncolored_tty_block = lambda do
 | |
|             instance_eval <<-EOS, __FILE__, __LINE__ + 1
 | |
|               begin                                                       # begin
 | |
|                 captured_stream = StringIO.new                            #   captured_stream = StringIO.new
 | |
| 
 | |
|                 original_stream = $#{@output}                             #   original_stream = $stdout
 | |
|                 $#{@output} = captured_stream                             #   $stdout = captured_stream
 | |
| 
 | |
|                 colored_tty_block.call                                    #   colored_tty_block.call
 | |
|               ensure                                                      # ensure
 | |
|                 $#{@output} = original_stream                             #   $stdout = original_stream
 | |
|                 $#{@output}.print Tty.strip_ansi(captured_stream.string)  #   $stdout.print Tty.strip_ansi(captured_stream.string)
 | |
|               end                                                         # end
 | |
|             EOS
 | |
|           end
 | |
| 
 | |
|           super(uncolored_tty_block)
 | |
|         end
 | |
| 
 | |
|         def to_stdout
 | |
|           @output = :stdout
 | |
|           super
 | |
|           self
 | |
|         end
 | |
| 
 | |
|         def to_stderr
 | |
|           @output = :stderr
 | |
|           super
 | |
|           self
 | |
|         end
 | |
| 
 | |
|         def as_tty
 | |
|           @tty = true
 | |
|           return self if [:stdout, :stderr].include?(@output)
 | |
| 
 | |
|           raise "`as_tty` can only be chained to `stdout` or `stderr`."
 | |
|         end
 | |
| 
 | |
|         def with_color
 | |
|           @colors = true
 | |
|           return self if @tty
 | |
| 
 | |
|           raise "`with_color` can only be chained to `as_tty`."
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def output(*args)
 | |
|         core_matcher = super(*args)
 | |
|         Output.new(core_matcher)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 | 
