Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: test/plugin/ExceptionTest.cpp

Issue 5137721374801920: Issue #1173 - Default behavior for catch-all blocks
Left Patch Set: Created Feb. 25, 2015, 9:44 p.m.
Right Patch Set: Changed entry point defaults in CPluginClass to match rebase Created March 20, 2015, 9:50 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« src/plugin/Exception.h ('K') | « src/plugin/PluginStdAfx.h ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include <gtest/gtest.h> 18 #include <gtest/gtest.h>
19
20 #include "../../src/plugin/Exception.h" 19 #include "../../src/plugin/Exception.h"
21
22 #include <stdexcept> 20 #include <stdexcept>
23 21
24 void AssignCurrentException(std::exception_ptr& e) 22 void AssignCurrentException(std::exception_ptr& e)
25 { 23 {
26 e = std::current_exception(); 24 e = std::current_exception();
27 } 25 }
28 26
29 /* 27 /*
30 * This test verifies that std::current_exception works during exception handlin g generally, 28 * This test verifies that std::current_exception works during exception handlin g generally,
31 * not just in the immediate context of a 'catch' clause. 29 * not just in the immediate context of a 'catch' clause.
32 */ 30 */
33 TEST(Exception, CurrentExceptionWorksOutsideCatchHandler) 31 TEST(Exception, CurrentExceptionWorksOutsideCatchHandler)
34 { 32 {
35 std::exception_ptr ep; 33 std::exception_ptr ep;
36 const auto e=std::runtime_error("BJTCiRhkVAmvMg"); 34 const auto e = std::runtime_error("BJTCiRhkVAmvMg");
Oleksandr 2015/02/27 10:48:36 Nit: Space before and after =
Eric 2015/02/27 15:36:50 Done.
37 try 35 try
38 { 36 {
39 throw e; 37 throw e;
40 } 38 }
41 catch (...) 39 catch (...)
42 { 40 {
43 AssignCurrentException(ep); 41 AssignCurrentException(ep);
44 ASSERT_TRUE(ep); 42 ASSERT_TRUE(ep);
45 /* 43 /*
46 * You might think that the next set would be EXPECT_EQ betwwen the thrown e xception and the original one. 44 * You might think that the next set would be EXPECT_EQ betwwen the thrown e xception and the original one.
(...skipping 23 matching lines...) Expand all
70 */ 68 */
71 class PlainException 69 class PlainException
72 : public std::exception 70 : public std::exception
73 { 71 {
74 const char* what() const override 72 const char* what() const override
75 { 73 {
76 return "Plain"; 74 return "Plain";
77 }; 75 };
78 }; 76 };
79 77
78 struct NullHandlers
79 {
80 static void Unknown(int y) {}
81 static void Exception(std::exception& ex,int y) {}
82 static void LogicError(std::logic_error& ex,int y) { Exception(ex, y); }
83 static void RuntimeError(std::runtime_error& ex,int y) { Exception(ex, y); }
84 static void SystemError(std::system_error& ex,int y) { RuntimeError(ex, y); }
85 };
86
80 /* 87 /*
81 * The trivial tests assure that nothing escapes the catch-all function, 88 * The trivial tests assure that nothing escapes the catch-all function,
82 * that is, we ensure that nothing is thrown or rethrown. 89 * that is, we ensure that nothing is thrown or rethrown.
83 */ 90 */
84 template<class X> 91 template<class X>
85 void TrivialVoid(X x) 92 void TrivialVoid(X x)
86 { 93 {
87 ASSERT_NO_THROW( 94 ASSERT_NO_THROW(
88 { 95 {
89 try 96 try
90 { 97 {
91 throw x; 98 throw x;
92 } 99 }
93 catch (...) 100 catch (...)
94 { 101 {
95 CatchAllVoid<NullHandlers>::Handler(); 102 CatchAllVoid<NullHandlers>::Handler(0);
96 } 103 }
97 }); 104 });
98 } 105 }
99 106
100 TEST(Exception, TrivialVoidUnknown) 107 TEST(Exception, TrivialVoidUnknown)
101 { 108 {
102 TrivialVoid(5); 109 TrivialVoid(5);
103 } 110 }
104 111
105 TEST(Exception, TrivialVoidException) 112 TEST(Exception, TrivialVoidException)
106 { 113 {
107 TrivialVoid(PlainException()); 114 TrivialVoid(PlainException());
108 } 115 }
109 116
110 TEST(Exception, TrivialVoidLogicError) 117 TEST(Exception, TrivialVoidLogicError)
111 { 118 {
112 TrivialVoid(std::logic_error("")); 119 TrivialVoid(std::logic_error(""));
113 } 120 }
114 121
115 TEST(Exception, TrivialVoidRuntimeError) 122 TEST(Exception, TrivialVoidRuntimeError)
116 { 123 {
117 TrivialVoid(std::runtime_error("")); 124 TrivialVoid(std::runtime_error(""));
118 } 125 }
119 126
120 TEST(Exception, TrivialVoidSystemError) 127 TEST(Exception, TrivialVoidSystemError)
121 { 128 {
122 TrivialVoid(std::system_error(std::error_code())); 129 TrivialVoid(std::system_error(std::error_code()));
123 } 130 }
124 131
125 enum ExceptionCode 132 enum
126 { 133 {
127 InvalidCode = -1, 134 InvalidCode = -1,
128 UnknownCode = 1, 135 UnknownCode = 1,
129 ExceptionCode, 136 ExceptionCode,
130 LogicErrorCode, 137 LogicErrorCode,
131 RuntimeErrorCode, 138 RuntimeErrorCode,
132 SystemErrorCode 139 SystemErrorCode
133 }; 140 };
134 141
135 struct NullHandlersReturn 142 struct NullHandlersReturn
136 { 143 {
137 typedef int return_t; 144 typedef int ReturnType;
138 static return_t Unknown() { return UnknownCode; } 145 static ReturnType Unknown(int) { return UnknownCode; }
139 static return_t Exception(std::exception& ex) { return ExceptionCode; } 146 static ReturnType Exception(std::exception& ex, int) { return ExceptionCode; }
140 static return_t LogicError(std::logic_error& ex) { return LogicErrorCode; } 147 static ReturnType LogicError(std::logic_error& ex, int) { return LogicErrorCod e; }
141 static return_t RuntimeError(std::runtime_error& ex) { return RuntimeErrorCode ; } 148 static ReturnType RuntimeError(std::runtime_error& ex, int) { return RuntimeEr rorCode; }
142 static return_t SystemError(std::system_error& ex) { return SystemErrorCode; } 149 static ReturnType SystemError(std::system_error& ex, int) { return SystemError Code; }
143 }; 150 };
144 151
145 template<class X> 152 template<class X>
146 void TrivialReturn(int n, X x) 153 void TrivialReturn(int n, X x)
147 { 154 {
148 ASSERT_NO_THROW( 155 ASSERT_NO_THROW(
149 { 156 {
150 try 157 try
151 { 158 {
152 throw x; 159 throw x;
153 } 160 }
154 catch (...) 161 catch (...)
155 { 162 {
156 ASSERT_EQ(n, CatchAllReturn<NullHandlersReturn>::Handler()); 163 ASSERT_EQ(n, CatchAllReturn<NullHandlersReturn>::Handler(0));
157 } 164 }
158 }); 165 });
159 } 166 }
160 167
161 TEST(Exception, TrivialReturnUnknown) 168 TEST(Exception, TrivialReturnUnknown)
162 { 169 {
163 TrivialReturn(UnknownCode, 5); 170 TrivialReturn(UnknownCode, 5);
164 } 171 }
165 172
166 TEST(Exception, TrivialReturnException) 173 TEST(Exception, TrivialReturnException)
167 { 174 {
168 TrivialReturn(ExceptionCode, PlainException()); 175 TrivialReturn(ExceptionCode, PlainException());
169 } 176 }
170 177
171 TEST(Exception, TrivialReturnLogicError) 178 TEST(Exception, TrivialReturnLogicError)
172 { 179 {
173 TrivialReturn(LogicErrorCode, std::logic_error("")); 180 TrivialReturn(LogicErrorCode, std::logic_error(""));
174 } 181 }
175 182
176 TEST(Exception, TrivialReturnRuntimeError) 183 TEST(Exception, TrivialReturnRuntimeError)
177 { 184 {
178 TrivialReturn(RuntimeErrorCode, std::runtime_error("")); 185 TrivialReturn(RuntimeErrorCode, std::runtime_error(""));
179 } 186 }
180 187
181 TEST(Exception, TrivialReturnSystemError) 188 TEST(Exception, TrivialReturnSystemError)
182 { 189 {
183 TrivialReturn(SystemErrorCode, std::system_error(std::error_code())); 190 TrivialReturn(SystemErrorCode, std::system_error(std::error_code()));
184 } 191 }
192
193 /*
194 * VS 2012 supports thread_local semantics for POD only, not arbitrary types.
195 * That's good enough for now.
196 * Remove the definition when VS matures.
197 */
198 #define thread_local __declspec(thread)
199
200 /*
201 * The sub-handlers are purely static functions,
202 * so getting them to return something unique for testing has possible race co nditions.
203 * We're using a thread-local variable as a return code from the simple handlers ,
204 * which ensures that even a multi-threaded test runner will work here.
205 */
206 thread_local int SimpleResult;
207 thread_local int SimpleExpected;
185 208
186 /* 209 /*
187 * The simple tests ensure that the flow of control arrives in the correct subha ndler. 210 * The simple tests ensure that the flow of control arrives in the correct subha ndler.
188 */ 211 */
189 template<class X, class H> 212 template<class X, class H>
190 void SimpleVoid(X x, H h) 213 void SimpleVoid(X x, H h)
214 {
215 SimpleResult = 0;
216 SimpleExpected = std::rand();
217 if (SimpleExpected == 0) { SimpleExpected = 1; }
218 ASSERT_NO_THROW(
219 {
220 try
221 {
222 throw x;
223 }
224 catch (...)
225 {
226 CatchAllVoid<H>::Handler(0);
227 }
228 });
229 EXPECT_EQ(SimpleExpected, SimpleResult);
230 }
231
232 /*
233 * The base handler class for the simple tests fails every execution path.
234 * Each specific test redefines a single one of the handler functions that it us es.
235 */
236 class SimpleHandlersBase
237 {
238 public:
239 static void Unknown(int) { FAIL() << "Unexpected exception of unknown type"; }
240 static void Exception(std::exception& ex, int) { FAIL() << "Unexpected std::ex ception"; }
241 static void LogicError(std::logic_error& ex, int) { FAIL() << "Unexpected std: :logic_error"; }
242 static void RuntimeError(std::runtime_error& ex, int) { FAIL() << "Unexpected std::runtime_error"; }
243 static void SystemError(std::system_error& ex, int) { FAIL() << "Unexpected st d::system_error"; };
244 protected:
245 static void Ping() { SimpleResult = SimpleExpected; }
246 };
247
248 TEST(Exception, SimpleVoidUnknown)
249 {
250 struct Handler :
251 public SimpleHandlersBase
252 {
253 static void Unknown(int) { Ping(); }
254 };
255 SimpleVoid(5, Handler());
256 }
257
258 TEST(Exception, SimpleVoidException)
259 {
260 struct Handler :
261 public SimpleHandlersBase
262 {
263 static void Exception(std::exception& ex, int) { Ping(); }
264 };
265 SimpleVoid(PlainException(), Handler());
266 }
267
268 TEST(Exception, SimpleVoidLogicError)
269 {
270 struct Handler :
271 public SimpleHandlersBase
272 {
273 static void LogicError(std::logic_error& ex, int) { Ping(); }
274 };
275 SimpleVoid(std::logic_error(""), Handler());
276 }
277
278 TEST(Exception, SimpleVoidRuntimeError)
279 {
280 struct Handler :
281 public SimpleHandlersBase
282 {
283 static void RuntimeError(std::runtime_error& ex, int) { Ping(); }
284 };
285 SimpleVoid(std::runtime_error(""), Handler());
286 }
287
288 TEST(Exception, SimpleVoidSystemError)
289 {
290 struct Handler :
291 public SimpleHandlersBase
292 {
293 static void SystemError(std::system_error& ex, int) { Ping(); }
294 };
295 SimpleVoid(std::system_error(std::error_code()), Handler());
296 }
297
298 template<class X, class H>
299 void SimpleReturn(int n, X x, H h)
191 { 300 {
192 SimpleResult = 0; 301 SimpleResult = 0;
193 SimpleExpected = rand(); 302 SimpleExpected = rand();
194 if (SimpleExpected == 0) { SimpleExpected = 1; } 303 if (SimpleExpected == 0) { SimpleExpected = 1; }
195 ASSERT_NO_THROW( 304 ASSERT_NO_THROW(
196 { 305 {
197 try 306 try
198 { 307 {
199 throw x; 308 throw x;
200 } 309 }
201 catch (...) 310 catch (...)
202 { 311 {
203 CatchAllVoid<H>::Handler(); 312 EXPECT_EQ(n, CatchAllReturn<H>::Handler(0));
204 } 313 }
205 }); 314 });
206 EXPECT_EQ(SimpleExpected, SimpleResult); 315 EXPECT_EQ(SimpleExpected, SimpleResult);
207 } 316 }
208 317
209 /* 318 /*
210 * VS 2012 supports thread_local semantics for POD only, not arbitrary types. 319 * The base handlers class fails every execution path.
211 * That's good enough for now. 320 */
212 * Remove the definition when VS matures. 321 class SimpleHandlersReturnBase
213 */
214 #define thread_local __declspec(thread)
215
216 /*
217 * The sub-handlers are purely static functions,
218 * so getting them to return something unique for testing has possible race co nditions.
219 * We're using a thread-local variable as a return code from the simple handlers ,
220 * which ensures that even a multi-threaded test runner will work here.
221 */
222 thread_local int SimpleResult;
223 thread_local int SimpleExpected;
224
225 /*
226 * The base handler class for the simple tests fails every execution path.
227 * Each specific test redefines a single one of the handler functions that it us es.
228 */
229 class SimpleHandlersBase
230 { 322 {
231 public: 323 public:
232 static void Unknown() { FAIL() << "Unexpected exception of unknown type"; } 324 typedef int ReturnType;
233 static void Exception(std::exception& ex) { FAIL() << "Unexpected std::excepti on"; } 325 static ReturnType Unknown(int) { ADD_FAILURE() << "Unexpected exception of unk nown type"; return InvalidCode; }
234 static void LogicError(std::logic_error& ex) { FAIL() << "Unexpected std::logi c_error"; } 326 static ReturnType Exception(std::exception& ex, int) { ADD_FAILURE() << "Unexp ected std::exception"; return InvalidCode; }
235 static void RuntimeError(std::runtime_error& ex) { FAIL() << "Unexpected std:: runtime_error"; } 327 static ReturnType LogicError(std::logic_error& ex, int) { ADD_FAILURE() << "Un expected std::logic_error"; return InvalidCode; }
236 static void SystemError(std::system_error& ex) { FAIL() << "Unexpected std::sy stem_error"; }; 328 static ReturnType RuntimeError(std::runtime_error& ex, int) { ADD_FAILURE() << "Unexpected std::runtime_error"; return InvalidCode; }
329 static ReturnType SystemError(std::system_error& ex, int) { ADD_FAILURE() << " Unexpected std::system_error"; return InvalidCode; }
237 protected: 330 protected:
238 static void Ping() { SimpleResult = SimpleExpected; } 331 static void Ping() { SimpleResult = SimpleExpected; }
239 }; 332 };
240 333
241 TEST(Exception, SimpleVoidUnknown)
242 {
243 struct Handler :
244 public SimpleHandlersBase
245 {
246 static void Unknown() { Ping(); }
247 };
248 SimpleVoid(5, Handler());
249 }
250
251 TEST(Exception, SimpleVoidException)
252 {
253 struct Handler :
254 public SimpleHandlersBase
255 {
256 static void Exception(std::exception& ex) { Ping(); }
257 };
258 SimpleVoid(PlainException(), Handler());
259 }
260
261 TEST(Exception, SimpleVoidLogicError)
262 {
263 struct Handler :
264 public SimpleHandlersBase
265 {
266 static void LogicError(std::logic_error& ex) { Ping(); }
267 };
268 SimpleVoid(std::logic_error(""), Handler());
269 }
270
271 TEST(Exception, SimpleVoidRuntimeError)
272 {
273 struct Handler :
274 public SimpleHandlersBase
275 {
276 static void RuntimeError(std::runtime_error& ex) { Ping(); }
277 };
278 SimpleVoid(std::runtime_error(""), Handler());
279 }
280
281 TEST(Exception, SimpleVoidSystemError)
282 {
283 struct Handler :
284 public SimpleHandlersBase
285 {
286 static void SystemError(std::system_error& ex) { Ping(); }
287 };
288 SimpleVoid(std::system_error(std::error_code()), Handler());
289 }
290
291 template<class X, class H>
292 void SimpleReturn(int n, X x, H h)
293 {
294 SimpleResult = 0;
295 SimpleExpected = rand();
296 if (SimpleExpected == 0) { SimpleExpected = 1; }
297 ASSERT_NO_THROW(
298 {
299 try
300 {
301 throw x;
302 }
303 catch (...)
304 {
305 EXPECT_EQ(n, CatchAllReturn<H>::Handler());
306 }
307 });
308 EXPECT_EQ(SimpleExpected, SimpleResult);
309 }
310
311 /*
312 * The base handlers class fails every execution path.
313 */
314 class SimpleHandlersReturnBase
315 {
316 public:
317 typedef int return_t;
318 static return_t Unknown() { ADD_FAILURE() << "Unexpected exception of unknown type"; return InvalidCode; }
319 static return_t Exception(std::exception& ex) { ADD_FAILURE() << "Unexpected s td::exception"; return InvalidCode; }
320 static return_t LogicError(std::logic_error& ex) { ADD_FAILURE() << "Unexpecte d std::logic_error"; return InvalidCode; }
321 static return_t RuntimeError(std::runtime_error& ex) { ADD_FAILURE() << "Unexp ected std::runtime_error"; return InvalidCode; }
322 static return_t SystemError(std::system_error& ex) { ADD_FAILURE() << "Unexpec ted std::system_error"; return InvalidCode; }
323 protected:
324 static void Ping() { SimpleResult = SimpleExpected; }
325 };
326
327 TEST(Exception, SimpleReturnUnknown) 334 TEST(Exception, SimpleReturnUnknown)
328 { 335 {
329 struct Handler : 336 struct Handler :
330 public SimpleHandlersReturnBase 337 public SimpleHandlersReturnBase
331 { 338 {
332 static int Unknown() { Ping(); return UnknownCode; } 339 static int Unknown(int) { Ping(); return UnknownCode; }
333 }; 340 };
334 SimpleReturn(UnknownCode, 5, Handler()); 341 SimpleReturn(UnknownCode, 5, Handler());
335 } 342 }
336 343
337 TEST(Exception, SimpleReturnException) 344 TEST(Exception, SimpleReturnException)
338 { 345 {
339 struct Handler : 346 struct Handler :
340 public SimpleHandlersReturnBase 347 public SimpleHandlersReturnBase
341 { 348 {
342 static int Exception(std::exception& ex) { Ping(); return ExceptionCode; } 349 static int Exception(std::exception& ex, int) { Ping(); return ExceptionCode ; }
343 }; 350 };
344 SimpleReturn(ExceptionCode, PlainException(), Handler()); 351 SimpleReturn(ExceptionCode, PlainException(), Handler());
345 } 352 }
346 353
347 TEST(Exception, SimpleReturnLogicError) 354 TEST(Exception, SimpleReturnLogicError)
348 { 355 {
349 struct Handler : 356 struct Handler :
350 public SimpleHandlersReturnBase 357 public SimpleHandlersReturnBase
351 { 358 {
352 static int LogicError(std::logic_error& ex) { Ping(); return LogicErrorCode; } 359 static int LogicError(std::logic_error& ex, int) { Ping(); return LogicError Code; }
353 }; 360 };
354 SimpleReturn(LogicErrorCode, std::logic_error(""), Handler()); 361 SimpleReturn(LogicErrorCode, std::logic_error(""), Handler());
355 } 362 }
356 363
357 TEST(Exception, SimpleReturnRuntimeError) 364 TEST(Exception, SimpleReturnRuntimeError)
358 { 365 {
359 struct Handler : 366 struct Handler :
360 public SimpleHandlersReturnBase 367 public SimpleHandlersReturnBase
361 { 368 {
362 static int RuntimeError(std::runtime_error& ex) { Ping(); return RuntimeErro rCode; } 369 static int RuntimeError(std::runtime_error& ex, int) { Ping(); return Runtim eErrorCode; }
363 }; 370 };
364 SimpleReturn(RuntimeErrorCode, std::runtime_error(""), Handler()); 371 SimpleReturn(RuntimeErrorCode, std::runtime_error(""), Handler());
365 } 372 }
366 373
367 TEST(Exception, SimpleReturnSystemError) 374 TEST(Exception, SimpleReturnSystemError)
368 { 375 {
369 struct Handler : 376 struct Handler :
370 public SimpleHandlersReturnBase 377 public SimpleHandlersReturnBase
371 { 378 {
372 static int SystemError(std::system_error& ex) { Ping(); return SystemErrorCo de; } 379 static int SystemError(std::system_error& ex, int) { Ping(); return SystemEr rorCode; }
373 }; 380 };
374 SimpleReturn(SystemErrorCode, std::system_error(std::error_code()), Handler()) ; 381 SimpleReturn(SystemErrorCode, std::system_error(std::error_code()), Handler()) ;
375 } 382 }
376 383
LEFTRIGHT

Powered by Google App Engine
This is Rietveld