summaryrefslogtreecommitdiff
path: root/spec/commands/cat_spec.rb
blob: 813ff4a1aca29a9945173453fad72970c011b076 (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
describe "cat" do
  before do
    @str_output = StringIO.new

    @t = pry_tester do
      def insert_nil_input
        @pry.update_input_history(nil)
      end

      def last_exception=(e)
        @pry.last_exception = e
      end
    end
  end

  describe "when invoked without arguments" do
    it 'should display an error message' do
      expect { @t.eval 'cat' }.to raise_error(Pry::CommandError, /Must provide a filename/)
    end
  end

  describe "on receiving a file that does not exist" do
    it 'should display an error message' do
      expect { @t.eval 'cat supercalifragilicious66' }.to raise_error(StandardError, /Cannot open/)
    end
  end

  describe "with --in" do
    it 'should display the last few expressions with indices' do
      expect(@t.eval('10', '20', 'cat --in')).to eq unindent(<<-STR)
        1:
          10
        2:
          20
      STR
    end
  end

  describe "with --in 1" do
    it 'should display the first expression with no index' do
      expect(@t.eval('10', '20', 'cat --in 1')).to eq("10\n")
    end
  end

  describe "with --in -1" do
    it 'should display the last expression with no index' do
      expect(@t.eval('10', '20', 'cat --in -1')).to eq("20\n")
    end
  end

  describe "with --in 1..2" do
    it 'should display the given range with indices, omitting nils' do
      @t.eval '10'
      @t.insert_nil_input # normally happens when a command is executed
      @t.eval ':hello'

      expect(@t.eval('cat --in 1..3')).to eq unindent(<<-EOS)
        1:
          10
        3:
          :hello
      EOS
    end
  end

  describe "with --ex" do
    before do
      @o = Object.new

      # this is to test exception code (cat --ex)
      def @o.broken_method
        this method is broken
      end
    end

    it 'cat --ex should display repl code that generated exception' do
      @t.eval unindent(<<-EOS)
        begin
          this raises error
        rescue => e
          _pry_.last_exception = e
        end
      EOS
      expect(@t.eval('cat --ex')).to match(/\d+:(\s*) this raises error/)
    end

    it 'cat --ex should correctly display code that generated exception' do
      begin
        @o.broken_method
      rescue => e
        @t.last_exception = e
      end
      expect(@t.eval('cat --ex')).to match(/this method is broken/)
    end
  end

  describe "with --ex N" do
    it 'should cat first level of backtrace when --ex used with no argument ' do
      temp_file do |f|
        f << "bt number 1"
        f.flush
        @t.last_exception = mock_exception("#{f.path}:1", 'x', 'x')
        expect(@t.eval('cat --ex')).to match(/bt number 1/)
      end
    end

    it 'should cat first level of backtrace when --ex 0 used ' do
      temp_file do |f|
        f << "bt number 1"
        f.flush
        @t.last_exception = mock_exception("#{f.path}:1", 'x', 'x')
        expect(@t.eval('cat --ex 0')).to match(/bt number 1/)
      end
    end

    it 'should cat second level of backtrace when --ex 1 used ' do
      temp_file do |f|
        f << "bt number 2"
        f.flush
        @t.last_exception = mock_exception('x', "#{f.path}:1", 'x')
        expect(@t.eval('cat --ex 1')).to match(/bt number 2/)
      end
    end

    it 'should cat third level of backtrace when --ex 2 used' do
      temp_file do |f|
        f << "bt number 3"
        f.flush
        @t.last_exception = mock_exception('x', 'x', "#{f.path}:1")
        expect(@t.eval('cat --ex 2')).to match(/bt number 3/)
      end
    end

    it 'should show error when backtrace level out of bounds' do
      @t.last_exception = mock_exception('x', 'x', 'x')
      expect { @t.eval('cat --ex 3') }.to raise_error(Pry::CommandError, /out of bounds/)
    end

    it 'each successive cat --ex should show the next level of backtrace, and going past the final level should return to the first' do
      temp_files = []
      3.times do |i|
        temp_files << Tempfile.new(['pry', '.rb'])
        temp_files.last << "bt number #{i}"
        temp_files.last.flush
      end

      @t.last_exception = mock_exception(*temp_files.map { |f| "#{f.path}:1" })

      3.times do |i|
        expect(@t.eval('cat --ex')).to match(/bt number #{i}/)
      end

      expect(@t.eval('cat --ex')).to match(/bt number 0/)

      temp_files.each do |file|
        file.close(true)
      end
    end
  end
end