summaryrefslogtreecommitdiff
path: root/spec/mspec/lib/mspec/helpers/io.rb
blob: 29c6c37a1a65c78a4b9792e25626bb6149f48ef3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
require 'mspec/guards/feature'

class IOStub
  def initialize
    @buffer = []
    @output = ''
  end

  def write(*str)
    self << str.join
  end

  def << str
    @buffer << str
    self
  end

  def print(*str)
    write(str.join + $\.to_s)
  end

  def method_missing(name, *args, &block)
    to_s.send(name, *args, &block)
  end

  def == other
    to_s == other
  end

  def =~ other
    to_s =~ other
  end

  def puts(*str)
    if str.empty?
      write "\n"
    else
      write(str.collect { |s| s.to_s.chomp }.concat([nil]).join("\n"))
    end
  end

  def printf(format, *args)
    self << sprintf(format, *args)
  end

  def flush
    @output += @buffer.join('')
    @buffer.clear
    self
  end

  def to_s
    flush
    @output
  end

  alias_method :to_str, :to_s

  def inspect
    to_s.inspect
  end
end

# Creates a "bare" file descriptor (i.e. one that is not associated
# with any Ruby object). The file descriptor can safely be passed
# to IO.new without creating a Ruby object alias to the fd.
def new_fd(name, mode = "w:utf-8")
  if mode.kind_of? Hash
    if mode.key? :mode
      mode = mode[:mode]
    else
      raise ArgumentError, "new_fd options Hash must include :mode"
    end
  end

  IO.sysopen name, mode
end

# Creates an IO instance for a temporary file name. The file
# must be deleted.
def new_io(name, mode = "w:utf-8")
  if Hash === mode # Avoid kwargs warnings on Ruby 2.7+
    File.new(name, **mode)
  else
    File.new(name, mode)
  end
end