summaryrefslogtreecommitdiff
path: root/spec/ruby/core/io/puts_spec.rb
blob: 8f2f4f2c81f7c557049a67a9bc1df827763cc2c9 (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
140
141
142
143
144
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

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
    $/ = @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
    lambda { $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.should_receive(:write).with("#<Object:0x...>")
    @io.should_receive(:write).with("\n")
    @io.puts(object).should == nil
  end

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

    @io.should_receive(:write).with("hola")
    @io.should_receive(:write).with("\n")
    @io.puts(object).should == nil
  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.should_receive(:write).with(object.inspect.split(" ")[0] + ">")
    @io.should_receive(:write).with("\n")
    @io.puts(object).should == nil
  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
    $/ = ":"
    @io.puts(5).should == nil
    ScratchPad.recorded.should == "5\n"
  end

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

  with_feature :encoding do
    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
end