aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/dispatch/exception_wrapper_test.rb
blob: 668469a01dafd1b8c8c396f4d297eeb0e8a10f40 (plain) (blame)
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
# frozen_string_literal: true

require "abstract_unit"

module ActionDispatch
  class ExceptionWrapperTest < ActionDispatch::IntegrationTest
    class TestError < StandardError
      attr_reader :backtrace

      def initialize(*backtrace)
        @backtrace = backtrace.flatten
      end
    end

    class BadlyDefinedError < StandardError
      def backtrace
        nil
      end
    end

    setup do
      @cleaner = ActiveSupport::BacktraceCleaner.new
      @cleaner.remove_filters!
      @cleaner.add_silencer { |line| line !~ /^lib/ }
    end

    test "#source_extracts fetches source fragments for every backtrace entry" do
      exception = TestError.new("lib/file.rb:42:in `index'")
      wrapper = ExceptionWrapper.new(nil, exception)

      assert_called_with(wrapper, :source_fragment, ["lib/file.rb", 42], returns: "foo") do
        assert_equal [ code: "foo", line_number: 42 ], wrapper.source_extracts
      end
    end

    test "#source_extracts works with Windows paths" do
      exc = TestError.new("c:/path/to/rails/app/controller.rb:27:in 'index':")

      wrapper = ExceptionWrapper.new(nil, exc)

      assert_called_with(wrapper, :source_fragment, ["c:/path/to/rails/app/controller.rb", 27], returns: "nothing") do
        assert_equal [ code: "nothing", line_number: 27 ], wrapper.source_extracts
      end
    end

    test "#source_extracts works with non standard backtrace" do
      exc = TestError.new("invalid")

      wrapper = ExceptionWrapper.new(nil, exc)

      assert_called_with(wrapper, :source_fragment, ["invalid", 0], returns: "nothing") do
        assert_equal [ code: "nothing", line_number: 0 ], wrapper.source_extracts
      end
    end

    test "#application_trace returns traces only from the application" do
      exception = TestError.new(caller.prepend("lib/file.rb:42:in `index'"))
      wrapper = ExceptionWrapper.new(@cleaner, exception)

      assert_equal [ "lib/file.rb:42:in `index'" ], wrapper.application_trace
    end

    test "#status_code returns 400 for Rack::Utils::ParameterTypeError" do
      exception = Rack::Utils::ParameterTypeError.new
      wrapper = ExceptionWrapper.new(@cleaner, exception)
      assert_equal 400, wrapper.status_code
    end

    test "#application_trace cannot be nil" do
      nil_backtrace_wrapper = ExceptionWrapper.new(@cleaner, BadlyDefinedError.new)
      nil_cleaner_wrapper = ExceptionWrapper.new(nil, BadlyDefinedError.new)

      assert_equal [], nil_backtrace_wrapper.application_trace
      assert_equal [], nil_cleaner_wrapper.application_trace
    end

    test "#framework_trace returns traces outside the application" do
      exception = TestError.new(caller.prepend("lib/file.rb:42:in `index'"))
      wrapper = ExceptionWrapper.new(@cleaner, exception)

      assert_equal caller, wrapper.framework_trace
    end

    test "#framework_trace cannot be nil" do
      nil_backtrace_wrapper = ExceptionWrapper.new(@cleaner, BadlyDefinedError.new)
      nil_cleaner_wrapper = ExceptionWrapper.new(nil, BadlyDefinedError.new)

      assert_equal [], nil_backtrace_wrapper.framework_trace
      assert_equal [], nil_cleaner_wrapper.framework_trace
    end

    test "#full_trace returns application and framework traces" do
      exception = TestError.new(caller.prepend("lib/file.rb:42:in `index'"))
      wrapper = ExceptionWrapper.new(@cleaner, exception)

      assert_equal exception.backtrace, wrapper.full_trace
    end

    test "#full_trace cannot be nil" do
      nil_backtrace_wrapper = ExceptionWrapper.new(@cleaner, BadlyDefinedError.new)
      nil_cleaner_wrapper = ExceptionWrapper.new(nil, BadlyDefinedError.new)

      assert_equal [], nil_backtrace_wrapper.full_trace
      assert_equal [], nil_cleaner_wrapper.full_trace
    end

    test "#traces returns every trace by category enumerated with an index" do
      exception = TestError.new("lib/file.rb:42:in `index'", "/gems/rack.rb:43:in `index'")
      wrapper = ExceptionWrapper.new(@cleaner, exception)

      assert_equal({
        "Application Trace" => [
          exception_object_id: exception.object_id,
          id: 0,
          trace: "lib/file.rb:42:in `index'"
        ],
        "Framework Trace" => [
          exception_object_id: exception.object_id,
          id: 1,
          trace: "/gems/rack.rb:43:in `index'"
        ],
        "Full Trace" => [
          {
            exception_object_id: exception.object_id,
            id: 0,
            trace: "lib/file.rb:42:in `index'"
          },
          {
            exception_object_id: exception.object_id,
            id: 1,
            trace: "/gems/rack.rb:43:in `index'"
          }
        ]
      }, wrapper.traces)
    end
  end
end