1 /**
2  * Module to handle exceptions.
3  *
4  * License:
5  *     MIT. See LICENSE for full details.
6  */
7 module dunit.error;
8 
9 /**
10  * Imports.
11  */
12 import core.exception;
13 import std..string;
14 
15 
16 /**
17  * An exception thrown when a unit test fails.
18  *
19  * This exception derives from AssertError to make it possible for
20  * these errors to be thrown from nothrow methods.
21  */
22 class DUnitAssertError : AssertError
23 {
24 	/**
25 	 * Values to display in the message.
26 	 */
27 	private string[] _log;
28 
29 	/**
30 	 * Constructor.
31 	 *
32 	 * Params:
33 	 *     message = The error message.
34 	 *     file = The file where the error occurred.
35 	 *     line = The line where the error occurred.
36 	 */
37 	this(string message, string file, size_t line) pure nothrow @safe
38 	{
39 		super(message, file, line);
40 	}
41 
42 	/**
43 	 * Return the exception log.
44 	 *
45 	 * Returns:
46 	 *     The error's logged info, expectations and error messages.
47 	 */
48 	public @property string[] log()
49 	{
50 		return this._log;
51 	}
52 
53 	/**
54 	 * Add a line of info to the exception log.
55 	 *
56 	 * Params:
57 	 *     caption = The caption.
58 	 *     value = The value.
59 	 *     icon = The icon before the caption.
60 	 */
61 	public void addInfo(T)(string caption, T value, string icon = "ℹ")
62 	{
63 		this._log ~= format("%s %s: %s", icon, caption, value);
64 	}
65 
66 	/**
67 	 * Add a line of typed info to the exception log.
68 	 *
69 	 * Params:
70 	 *     caption = The caption.
71 	 *     value = The value.
72 	 *     icon = The icon before the caption.
73 	 */
74 	public void addTypedInfo(T)(string caption, T value, string icon = "ℹ")
75 	{
76 		this._log ~= format("%s %s: (%s) %s", icon, caption, T.stringof, value);
77 	}
78 
79 	/**
80 	 * Add a line of expected info to the exception log.
81 	 *
82 	 * Params:
83 	 *     caption = The caption.
84 	 *     value = The value.
85 	 *     icon = The icon before the caption.
86 	 */
87 	public void addExpectation(T)(string caption, T value, string icon = "✓")
88 	{
89 		this.addInfo!(T)(caption, value, icon);
90 	}
91 
92 	/**
93 	 * Add a line of typed expected info to the exception log.
94 	 *
95 	 * Params:
96 	 *     caption = The caption.
97 	 *     value = The value.
98 	 *     icon = The icon before the caption.
99 	 */
100 	public void addTypedExpectation(T)(string caption, T value, string icon = "✓")
101 	{
102 		this.addTypedInfo!(T)(caption, value, icon);
103 	}
104 
105 	/**
106 	 * Add a line of error info to the exception log.
107 	 *
108 	 * Params:
109 	 *     caption = The caption.
110 	 *     value = The value.
111 	 *     icon = The icon before the caption.
112 	 */
113 	public void addError(T)(string caption, T value, string icon = "✗")
114 	{
115 		this.addInfo!(T)(caption, value, icon);
116 	}
117 
118 	/**
119 	 * Add a line of typed error info to the exception log.
120 	 *
121 	 * Params:
122 	 *     caption = The caption.
123 	 *     value = The value.
124 	 *     icon = The icon before the caption.
125 	 */
126 	public void addTypedError(T)(string caption, T value, string icon = "✗")
127 	{
128 		this.addTypedInfo!(T)(caption, value, icon);
129 	}
130 }
131 
132 unittest
133 {
134 	import dunit.toolkit;
135 
136 	auto error = new DUnitAssertError("Error message.", "test.d", 100);
137 	error.addInfo("Info", 1);
138 	error.addTypedInfo("Typed info", 2);
139 	error.addExpectation("Expectation", 3);
140 	error.addTypedExpectation("Typed expectation", 4);
141 	error.addError("Error", 5);
142 	error.addTypedError("Typed error", 6);
143 
144 	try
145 	{
146 		throw error;
147 	}
148 	catch (DUnitAssertError ex)
149 	{
150 		ex.msg.assertEqual("Error message.");
151 		ex.file.assertEqual("test.d");
152 		ex.line.assertEqual(100);
153 		ex.log.assertEqual(["ℹ Info: 1", "ℹ Typed info: (int) 2", "✓ Expectation: 3", "✓ Typed expectation: (int) 4", "✗ Error: 5", "✗ Typed error: (int) 6"]);
154 	}
155 }