Module: Uspec::Errors

Extended by:
Terminal
Defined in:
lib/uspec/errors.rb

Constant Summary collapse

MSG_USPEC_BUG_URL =
"https://github.com/acook/uspec/issues/new"
MSG_IF_USPEC_BUG =
"If you think this is a bug in Uspec please report it: #{MSG_USPEC_BUG_URL}"
TRACE_EXCLUDE_PATTERN =
/#{Uspec.libpath.join 'lib'}|#{Uspec.libpath.join 'bin'}/

Class Method Summary collapse

Methods included from Terminal

color, colors, esc, hspace, method_missing, newline, normal, vspace

Class Method Details

.bt_clean(bt, skip_internal = true) ⇒ Object



149
150
151
152
153
154
# File 'lib/uspec/errors.rb', line 149

def bt_clean bt, skip_internal = true
  bt.inject(Array.new) do |t, line|
    next t if skip_internal && line.match(TRACE_EXCLUDE_PATTERN)
    t << bt_rewrite_caller(line)
  end if bt
end

.bt_format(bt, skip_internal = true) ⇒ Object



140
141
142
143
# File 'lib/uspec/errors.rb', line 140

def bt_format bt, skip_internal = true
  skip_internal = skip_internal && !full_backtrace?
  bt_indent bt_clean(bt, skip_internal)
end

.bt_get(error) ⇒ Object



105
106
107
# File 'lib/uspec/errors.rb', line 105

def bt_get error
  error.backtrace || caller[3..-1]
end

.bt_indent(bt) ⇒ Object



145
146
147
# File 'lib/uspec/errors.rb', line 145

def bt_indent bt
  "#{newline}#{hspace}" + bt.join("#{newline}#{hspace}") + newline if bt
end

.bt_rewrite_caller(line) ⇒ Object



156
157
158
159
160
161
162
163
# File 'lib/uspec/errors.rb', line 156

def bt_rewrite_caller line
  return line if full_backtrace?
  if line.match TRACE_EXCLUDE_PATTERN then
    line
  else
    line.sub /file_eval/, 'spec_block'
  end
end

.clean_backtrace!Object



173
174
175
# File 'lib/uspec/errors.rb', line 173

def clean_backtrace!
  @full_backtrace = false
end

.error_context(error, skip_internal: true) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/uspec/errors.rb', line 95

def error_context error, skip_internal: true
  bt = bt_get error
  error_line = bt.first.split(?:)
  [
    error_origin(*error_line),
    white(bt_format(bt, skip_internal)),
    MSG_IF_USPEC_BUG
  ].join ?\n
end

.error_format(error, message, first_line_indent: true, leading_newline: true, header: true) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/uspec/errors.rb', line 113

def error_format error, message, first_line_indent: true, leading_newline: true, header: true
  h = ""

  if header then
    h << newline if leading_newline
    h << hspace if first_line_indent
    h << error_header(error)
    h << vspace
  end

  error_indent(error, h + message)
end

.error_header(error) ⇒ Object



132
133
134
# File 'lib/uspec/errors.rb', line 132

def error_header error
  "#{red subklassinfo error}#{error.message}"
end

.error_indent(error, message) ⇒ Object



126
127
128
129
130
# File 'lib/uspec/errors.rb', line 126

def error_indent error, message
  a = message.split(newline)
  a << ""
  a.join("#{newline}#{hspace}")
end

.error_origin(error_file, error_line, *_) ⇒ Object



109
110
111
# File 'lib/uspec/errors.rb', line 109

def error_origin error_file, error_line, *_
  "The origin of the error may be in file `#{error_file}` on line ##{error_line}."
end

.full_backtrace!Object



169
170
171
# File 'lib/uspec/errors.rb', line 169

def full_backtrace!
  @full_backtrace = true
end

.full_backtrace?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/uspec/errors.rb', line 165

def full_backtrace?
  @full_backtrace
end

.handle_error(message, error, cli) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/uspec/errors.rb', line 39

def handle_error message, error, cli
  result = Uspec::Result.new(message, error, true)

  puts
  warn error_format error, message, leading_newline: false

  cli.handle_interrupt! result.raw if cli
  result
end

.handle_file_error(error, path, cli = nil) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/uspec/errors.rb', line 13

def handle_file_error error, path, cli = nil
  error_info = error_context error

  message = <<~MSG
    Uspec encountered an error when loading a test file.
    This is probably a typo in the test file or the file it is testing.

    Error occured when loading test file `#{path}`.
    #{error_info}
  MSG

  handle_error message, error, cli
end

.handle_internal_error(error, cli = nil) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/uspec/errors.rb', line 27

def handle_internal_error error, cli = nil
  error_info = error_context error, skip_internal: false

  message = <<~MSG
    Uspec encountered an internal error!

    #{error_info}
  MSG

  handle_error message, error, cli
end

.msg_source_error(error, desc, cli = nil) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/uspec/errors.rb', line 77

def msg_source_error error, desc, cli = nil
  error_info = error_context error

  message = <<~MSG
    Uspec detected a bug in your source code!

    Calling #inspect on an object will recusively call #inspect on its instance variables and contents.
    If one of those contained objects does not have an #inspect method you will see this message.
    You will also get this message if your #inspect method or one of its callees raises an exception.
    This is most likely to happen with BasicObject and its subclasses.

    Error occured when evaluating spec `#{desc}`.
    #{error_info}
  MSG

  error_format error, message, first_line_indent: false
end

.msg_spec_error(error, desc) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/uspec/errors.rb', line 49

def msg_spec_error error, desc
  error_info = error_context error

  info = <<~MSG
    Error occured when evaluating spec `#{desc}`.
    #{error_info}
  MSG
  body = error_format error, info, first_line_indent: false

  message = <<~MSG
    #{red 'Exception'}
    #{body}
  MSG

  message
end

.msg_spec_value(error) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/uspec/errors.rb', line 66

def msg_spec_value error
  error_info = white bt_format(bt_get error).chomp

  message = <<~MSG
    #{error.message}
    #{error_info}
  MSG

  error_format error, message, header: false
end

.subklassinfo(obj) ⇒ Object



136
137
138
# File 'lib/uspec/errors.rb', line 136

def subklassinfo obj
  "#{::TOISB.wrap(obj).subklassinfo}: "
end