Skip to content
This repository
tree: 461594e042
Fetching contributors…

Cannot retrieve contributors at this time

file 222 lines (183 sloc) 5.658 kb
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
# -*- encoding: utf-8 -*-
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

describe "IO#readlines" do
  before :each do
    @io = IOSpecs.io_fixture "lines.txt"
  end

  after :each do
    @io.close unless @io.closed?
  end

  ruby_version_is "1.9" do
    before :each do
      Encoding.default_external = Encoding::UTF_8
      @orig_exteenc = Encoding.default_external
    end

    after :each do
      Encoding.default_external = @orig_exteenc
    end
  end

  it "raises an IOError if the stream is closed" do
    @io.close
    lambda { @io.readlines }.should raise_error(IOError)
  end

  describe "when passed no arguments" do
    before :each do
      @sep, $/ = $/, " "
    end

    after :each do
      $/ = @sep
    end

    it "returns an Array containing lines based on $/" do
      @io.readlines.should == IOSpecs.lines_space_separator
    end
  end

  describe "when passed no arguments" do
    it "updates self's position" do
      @io.readlines
      @io.pos.should eql(137)
    end

    it "updates self's lineno based on the number of lines read" do
      @io.readlines
      @io.lineno.should eql(9)
    end

    it "does not change $_" do
      $_ = "test"
      @io.readlines
      $_.should == "test"
    end

    it "returns an empty Array when self is at the end" do
      @io.readlines.should == IOSpecs.lines
      @io.readlines.should == []
    end
  end

  describe "when passed nil" do
    it "returns the remaining content as one line starting at the current position" do
      @io.readlines(nil).should == [IOSpecs.lines.join]
    end
  end

  describe "when passed an empty String" do
    it "returns an Array containing all paragraphs" do
      @io.readlines("").should == IOSpecs.paragraphs
    end
  end

  describe "when passed a separator" do
    it "returns an Array containing lines based on the separator" do
      @io.readlines("r").should == IOSpecs.lines_r_separator
    end

    it "returns an empty Array when self is at the end" do
      @io.readlines
      @io.readlines("r").should == []
    end

    it "updates self's lineno based on the number of lines read" do
      @io.readlines("r")
      @io.lineno.should eql(5)
    end

    it "updates self's position based on the number of characters read" do
      @io.readlines("r")
      @io.pos.should eql(137)
    end

    it "does not change $_" do
      $_ = "test"
      @io.readlines("r")
      $_.should == "test"
    end

    it "tries to convert the passed separator to a String using #to_str" do
      obj = mock('to_str')
      obj.stub!(:to_str).and_return("r")
      @io.readlines(obj).should == IOSpecs.lines_r_separator
    end
  end

  describe "when passed a string that starts with a |" do
    it "gets data from the standard out of the subprocess" do
      lines = IO.readlines("|sh -c 'echo hello;echo line2'")
      lines.should == ["hello\n", "line2\n"]
    end

    it "gets data from a fork when passed -" do
      lines = IO.readlines("|-")

      if lines # parent
        lines.should == ["hello\n", "from a fork\n"]
      else
        puts "hello"
        puts "from a fork"
        exit!
      end
    end
  end
end

describe "IO#readlines" do
  before :each do
    @name = tmp("io_readlines")
  end

  after :each do
    rm_r @name
  end

  it "raises an IOError if the stream is opened for append only" do
    lambda do
      File.open(@name, fmode("a:utf-8")) { |f| f.readlines }
    end.should raise_error(IOError)
  end

  it "raises an IOError if the stream is opened for write only" do
    lambda do
      File.open(@name, fmode("w:utf-8")) { |f| f.readlines }
    end.should raise_error(IOError)
  end
end

describe "IO.readlines" do
  before(:each) do
    @name = fixture __FILE__, "lines.txt"
  end

  describe "when not passed a separator" do
    before :each do
      @sep, $/ = $/, " "
    end

    after :each do
      $/ = @sep
    end

    it "returns an Array containing lines of file_name based on $/" do
      IO.readlines(@name).should == IOSpecs.lines_space_separator
    end
  end

  describe "when not passed a separator" do
    it "raises an Errno::ENOENT error when the passed file_name does not exist" do
      lambda { IO.readlines(tmp("nonexistent.txt")) }.should raise_error(Errno::ENOENT)
    end

    it "does not change $_" do
      $_ = "test"
      IO.readlines(@name)
      $_.should == "test"
    end

    it "tries to convert the passed file_name to a String using #to_str" do
      obj = mock('IO.readlines filename')
      obj.stub!(:to_str).and_return(@name)
      IO.readlines(obj).should == IOSpecs.lines
    end
  end

  describe "when passed nil as a separator" do
    it "returns the contents as a single String" do
      IO.readlines(@name, nil).should == [IOSpecs.lines.join]
    end
  end

  describe "when passed an empty String as a separator" do
    it "returns an Array containing all paragraphs" do
      IO.readlines(@name, "").should == IOSpecs.paragraphs
    end
  end

  describe "when passed an arbitrary string separator" do
    it "returns an Array containing lines of file_name based on the passed separator" do
      IO.readlines(@name, "r").should == IOSpecs.lines_r_separator
    end

    it "does not change $_" do
      $_ = "test"
      IO.readlines(@name, "r")
      $_.should == "test"
    end
  end

  describe "when passed an object as separator" do
    it "tries to convert the passed separator to a String using #to_str" do
      obj = mock('IO.readlines filename')
      obj.stub!(:to_str).and_return("r")
      IO.readlines(@name, obj).should == IOSpecs.lines_r_separator
    end
  end
end
Something went wrong with that request. Please try again.