/
about_exceptions.rb
80 lines (66 loc) · 2.25 KB
/
about_exceptions.rb
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
require File.expand_path(File.dirname(__FILE__) + '/neo')
class AboutExceptions < Neo::Koan
class MySpecialError < RuntimeError
end
# Ancestors of a class are listed in ascending order in the hierarchy, i.e.
# [RuntimeError, StandardError, Exception, Object, ...]
def test_exceptions_inherit_from_Exception
assert_equal RuntimeError, MySpecialError.ancestors[1]
assert_equal StandardError, MySpecialError.ancestors[2]
assert_equal Exception, MySpecialError.ancestors[3]
assert_equal Object, MySpecialError.ancestors[4]
end
# fail() throws a RuntimeError with an optional message argument.
#
# Note that rescue StandardError => ex handles StandardError and any
# descendent classes. Also, note the syntax to capture the exception:
#
# rescue StandardError => ex
def test_rescue_clause
result = nil
begin
fail "Oops"
rescue StandardError => ex
result = :exception_handled
end
assert_equal :exception_handled, result
assert_equal true, ex.is_a?(StandardError), "Should be a Standard Error"
assert_equal true, ex.is_a?(RuntimeError), "Should be a Runtime Error"
assert RuntimeError.ancestors.include?(StandardError),
"RuntimeError is a subclass of StandardError"
assert_equal 'Oops', ex.message
end
def test_raising_a_particular_error
result = nil
begin
# 'raise' and 'fail' are synonyms
# Didn't know this!!!
raise MySpecialError, "My Message"
rescue MySpecialError => ex
result = :exception_handled
end
assert_equal :exception_handled, result
assert_equal 'My Message', ex.message
end
# Note that calling fail/raise without specifying a type will default to
# throwing a StandardError exception
def test_ensure_clause
result = nil
begin
fail "Oops"
rescue StandardError
# no code here
ensure
result = :always_run
end
# begin/rescue/ensure maps to C#'s try/catch/finally blocks
assert_equal :always_run, result
end
# Sometimes, we must know about the unknown
def test_asserting_an_error_is_raised
# A do-end is a block, a topic to explore more later
assert_raise(MySpecialError) do
raise MySpecialError.new("New instances can be raised directly.")
end
end
end