summaryrefslogtreecommitdiff
path: root/spec/ruby/core/io/puts_spec.rb
blob: 9a708fffef1a6eedccf328d3e05669edfa3e642a (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

describe "IO#puts" do
  before :each do
    @before_separator = $/
    @name = tmp("io_puts.txt")
    @io = new_io @name
    ScratchPad.record ""
    def @io.write(str)
      ScratchPad << str
    end
  end

  after :each do
    ScratchPad.clear
    @io.close if @io
    rm_r @name
    suppress_warning {$/ = @before_separator}
  end

  it "writes just a newline when given no args" do
    @io.puts.should == nil
    ScratchPad.recorded.should == "\n"
  end

  it "writes just a newline when given just a newline" do
    -> { $stdout.puts "\n" }.should output_to_fd("\n", $stdout)
  end

  it "writes empty string with a newline when given nil as an arg" do
    @io.puts(nil).should == nil
    ScratchPad.recorded.should == "\n"
  end

  it "writes empty string with a newline when when given nil as multiple args" do
    @io.puts(nil, nil).should == nil
    ScratchPad.recorded.should == "\n\n"
  end

  it "calls :to_ary before writing non-string objects, regardless of it being implemented in the receiver" do
    object = mock('hola')
    object.should_receive(:method_missing).with(:to_ary)
    object.should_receive(:to_s).and_return("#<Object:0x...>")

    @io.puts(object).should == nil
    ScratchPad.recorded.should == "#<Object:0x...>\n"
  end

  it "calls :to_ary before writing non-string objects" do
    object = mock('hola')
    object.should_receive(:to_ary).and_return(["hola"])

    @io.puts(object).should == nil
    ScratchPad.recorded.should == "hola\n"
  end

  it "calls :to_s before writing non-string objects that don't respond to :to_ary" do
    object = mock('hola')
    object.should_receive(:to_s).and_return("hola")

    @io.puts(object).should == nil
    ScratchPad.recorded.should == "hola\n"
  end

  it "returns general object info if :to_s does not return a string" do
    object = mock('hola')
    object.should_receive(:to_s).and_return(false)

    @io.puts(object).should == nil
    ScratchPad.recorded.should == object.inspect.split(" ")[0] + ">\n"
  end

  it "writes each arg if given several" do
    @io.puts(1, "two", 3).should == nil
    ScratchPad.recorded.should == "1\ntwo\n3\n"
  end

  it "flattens a nested array before writing it" do
    @io.puts([1, 2, [3]]).should == nil
    ScratchPad.recorded.should == "1\n2\n3\n"
  end

  it "writes nothing for an empty array" do
    x = []
    @io.should_not_receive(:write)
    @io.puts(x).should == nil
  end

  it "writes [...] for a recursive array arg" do
    x = []
    x << 2 << x
    @io.puts(x).should == nil
    ScratchPad.recorded.should == "2\n[...]\n"
  end

  it "writes a newline after objects that do not end in newlines" do
    @io.puts(5).should == nil
    ScratchPad.recorded.should == "5\n"
  end

  it "does not write a newline after objects that end in newlines" do
    @io.puts("5\n").should == nil
    ScratchPad.recorded.should == "5\n"
  end

  it "ignores the $/ separator global" do
    suppress_warning {$/ = ":"}
    @io.puts(5).should == nil
    ScratchPad.recorded.should == "5\n"
  end

  it "raises IOError on closed stream" do
    -> { IOSpecs.closed_io.puts("stuff") }.should raise_error(IOError)
  end

  it "writes crlf when IO is opened with newline: :crlf" do
    File.open(@name, 'wt', newline: :crlf) do |file|
      file.puts
    end
    File.binread(@name).should == "\r\n"
  end

  it "writes cr when IO is opened with newline: :cr" do
    File.open(@name, 'wt', newline: :cr) do |file|
      file.puts
    end
    File.binread(@name).should == "\r"
  end

  platform_is_not :windows do # https://bugs.ruby-lang.org/issues/12436
    it "writes lf when IO is opened with newline: :lf" do
      File.open(@name, 'wt', newline: :lf) do |file|
        file.puts
      end
      File.binread(@name).should == "\n"
    end
  end
end