BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsls_asserttest.h
Go to the documentation of this file.
1/// @file bsls_asserttest.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_asserttest.h -*-C++-*-
8#ifndef INCLUDED_BSLS_ASSERTTEST
9#define INCLUDED_BSLS_ASSERTTEST
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_asserttest bsls_asserttest
15/// @brief Provide a test facility for assertion macros.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_asserttest
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_asserttest-purpose"> Purpose</a>
25/// * <a href="#bsls_asserttest-classes"> Classes </a>
26/// * <a href="#bsls_asserttest-macros"> Macros </a>
27/// * <a href="#bsls_asserttest-description"> Description </a>
28/// * <a href="#bsls_asserttest-negative-testing"> Negative Testing </a>
29/// * <a href="#bsls_asserttest-a-note-on-exceptions"> A Note On Exceptions </a>
30/// * <a href="#bsls_asserttest-the-test-facility"> The Test Facility </a>
31/// * <a href="#bsls_asserttest-installing-the-assert-failure-handler"> Installing the Assert-Failure Handler </a>
32/// * <a href="#bsls_asserttest-basic-test-macros"> Basic Test Macros </a>
33/// * <a href="#bsls_asserttest-raw-test-macros"> Raw Test Macros </a>
34/// * <a href="#bsls_asserttest-enabling-negative-testing"> Enabling Negative Testing </a>
35/// * <a href="#bsls_asserttest-validating-disabled-macro-statements"> Validating Disabled Macro Statements </a>
36/// * <a href="#bsls_asserttest-validating-macro-testing-levels"> Validating Macro Testing Levels </a>
37/// * <a href="#bsls_asserttest-addtional-test-pass-macros"> Addtional Test Pass Macros </a>
38/// * <a href="#bsls_asserttest-usage"> Usage </a>
39/// * <a href="#bsls_asserttest-example-1-testing-assertions-in-a-simple-vector-implementation"> Example 1: Testing Assertions In A Simple Vector Implementation </a>
40/// * <a href="#bsls_asserttest-example-2-using-pass-macros-to-help-with-formatting"> Example 2: Using PASS macros to help with formatting </a>
41///
42/// # Purpose {#bsls_asserttest-purpose}
43/// Provide a test facility for assertion macros.
44///
45/// # Classes {#bsls_asserttest-classes}
46///
47/// - bsls::AssertTest: namespace for "assert" validating functions
48/// - bsls::AssertTestHandlerGuard: guard for the negative testing assert-handler
49///
50/// # Macros {#bsls_asserttest-macros}
51///
52/// - BSLS_ASSERTTEST_ASSERT_FAIL(STATEMENT): macro failure expected
53/// - BSLS_ASSERTTEST_ASSERT_FAIL_RAW(STATEMENT): no origination check
54/// - BSLS_ASSERTTEST_ASSERT_PASS(STATEMENT): macro success expected
55/// - BSLS_ASSERTTEST_ASSERT_PASS_RAW(STATEMENT): macro success expected
56/// - BSLS_ASSERTTEST_ASSERT_OPT_FAIL(STATEMENT): "opt" macro failure expected
57/// - BSLS_ASSERTTEST_ASSERT_OPT_FAIL_RAW(STATEMENT): no origination check
58/// - BSLS_ASSERTTEST_ASSERT_OPT_PASS(STATEMENT): macro success expected
59/// - BSLS_ASSERTTEST_ASSERT_OPT_PASS_RAW(STATEMENT): macro success expected
60/// - BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(STATEMENT): "safe" macro failure expected
61/// - BSLS_ASSERTTEST_ASSERT_SAFE_FAIL_RAW(STATEMENT): no origination check
62/// - BSLS_ASSERTTEST_ASSERT_SAFE_PASS(STATEMENT): macro success expected
63/// - BSLS_ASSERTTEST_ASSERT_SAFE_PASS_RAW(STATEMENT): macro success expected
64/// - BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL(STATEMENT): "invoke" macro expected
65/// - BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL_RAW(STATEMENT): no origination check
66/// - BSLS_ASSERTTEST_ASSERT_INVOKE_PASS(STATEMENT): macro success expected
67/// - BSLS_ASSERTTEST_ASSERT_INVOKE_PASS_RAW(STATEMENT): macro success expected
68///
69/// @see bsls_assert, bsls_asserttestexception
70///
71/// # Description {#bsls_asserttest-description}
72/// This component provides a facility to test that `BSLS_ASSERT_*`
73/// macros are used as intended, in the appropriate build modes, and have the
74/// expected effects. The class `bsls::AssertTest` provides a small set of
75/// static methods that can be used to support detailed test cases, especially
76/// in table-driven test scenarios. Additionally, a set of macros automate use
77/// of these methods to support simple testing of single statements or
78/// expressions.
79///
80/// A testing-specific handler guard, `bsls::AssertTestHandlerGuard`, is also
81/// provided to be used wherever the `BSLS_ASSERTTEST_*` macros are used.
82///
83/// ## Negative Testing {#bsls_asserttest-negative-testing}
84///
85///
86/// "Negative testing" is the principle of testing for a negative result, which
87/// implies the function under test must fail in some way. Testable failures
88/// typically occur when a function is called with values outside the defined
89/// contract: a well-implemented function will validate function arguments, in
90/// appropriate build modes, using the various `BSLS_ASSERT` macros (see
91/// @ref bsls_assert ). When a function fails as a result of an assertion, the
92/// default behavior is to terminate the program. However, the @ref bsls_assert
93/// facility allows a user-supplied assertion-failure handler function to be
94/// installed, which can be used to build a test facility for expected
95/// assertions.
96///
97/// One important issue to be aware of with negative testing is that you are
98/// testing undefined behavior within a program. For the purpose of the test
99/// driver, the behavior of calling a function outside its contract is well-
100/// defined if it is guarded by assertions that are active in the current build
101/// mode. However, it is important that those tests are not run if the assert
102/// macros are not active, otherwise truly undefined behavior will result, with
103/// potentially disastrous consequences.
104///
105/// ### A Note On Exceptions {#bsls_asserttest-a-note-on-exceptions}
106///
107///
108/// It is important to note that this facility relies on throwing and catching
109/// an exception in order to identify that an assertion has been violated,
110/// cleanup any objects created on the way to that assertion, and avoid
111/// executing any of the code after that assertion with deliberately bad input.
112/// This means that this component cannot be used to test assertions in
113/// functions that are `noexcept`, particular destructors that are implicitly
114/// `noexcept` in C++11 and beyond.
115///
116/// For most functions, if you have a narrow contract you should not be
117/// `noexcept`, as this is guaranteeing part of your behavior when your contract
118/// is violated (and actively preventing you from doing negative testing in this
119/// manner). For functions such as a destructor that are implicitly `noexcept`
120/// and greatly benefit from being so, it is advisable to move the checks into a
121/// separate `validate` method, and test destruction out of contract by just
122/// testing that the validate method asserts instead.
123///
124/// ## The Test Facility {#bsls_asserttest-the-test-facility}
125///
126///
127///
128/// ### Installing the Assert-Failure Handler {#bsls_asserttest-installing-the-assert-failure-handler}
129///
130///
131/// The function `bsls::AssertTest::failTestDriver` (and the parallel function
132/// `bsls::AssertTest::failTestDriverByReview`) is provided as the basis for a
133/// negative testing facility. It can act as an assertion-failure handler
134/// function that throws an exception, of type `bsls::AssertTestException`,
135/// containing the text of the failed assertion, the name of the file where it
136/// triggered, and the relevant line number within that file. The filename can
137/// be tested to ensure that the assertion was raised by the component under
138/// test, rather than by some deeper implementation detail as a consequence of
139/// the expected assertion not being present in the function under test.
140///
141/// Once the function `bsls::AssertTest::failTestDriver` has been registered as
142/// the active assertion-failure handler, a set of testing macros automate much
143/// of the boilerplate code involved in writing a negative test, so that a test
144/// can be effectively written as a single line. This is an important quality
145/// for reading tests, to clearly see the test logic in action without being
146/// distracted by the surrounding machinery.
147///
148/// ### Basic Test Macros {#bsls_asserttest-basic-test-macros}
149///
150///
151/// The five basic test macros are
152/// * `BSLS_ASSERTTEST_ASSERT_PASS`
153/// * `BSLS_ASSERTTEST_ASSERT_SAFE_FAIL`
154/// * `BSLS_ASSERTTEST_ASSERT_FAIL`
155/// * `BSLS_ASSERTTEST_ASSERT_OPT_FAIL`
156/// * `BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL`
157/// Each of these macros takes a single statement or expression as an argument,
158/// tests whether an assertion is raised while evaluating that expression, and,
159/// if an assertion is both raised and expected, whether that assertion was
160/// raised by the component under test.
161///
162/// A test failure is indicated by invoking `ASSERT(EXPRESSION)`, where `ASSERT`
163/// is either a macro or function that must be defined by the test driver, and
164/// `EXPRESSION` is an expression that evaluates to `true` or `false` according
165/// to whether the `ASSERTTEST_ASSERT` macro was expected to `_PASS` or `_FAIL`.
166///
167/// For example, if we have `std::vector<int> v` and `v` is empty, then the
168/// macro test `BSLS_ASSERTTEST_ASSERT_SAFE_FAIL((v.back()))` will fail when the
169/// effective assertion-level is `BSLS_ASSERT_LEVEL_ASSERT_SAFE` unless an
170/// assertion is raised. However, if the assertion-level is not
171/// `BSLS_ASSERT_LEVEL_ASSERT_SAFE`, then the test will not be run.
172///
173/// ### Raw Test Macros {#bsls_asserttest-raw-test-macros}
174///
175///
176/// The four "raw" test macros are
177/// * `BSLS_ASSERTTEST_ASSERT_SAFE_FAIL_RAW`
178/// * `BSLS_ASSERTTEST_ASSERT_FAIL_RAW`
179/// * `BSLS_ASSERTTEST_ASSERT_OPT_FAIL_RAW`
180/// * `BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL_RAW`
181/// These testing macros perform the same test as the corresponding basic
182/// testing macros, except that there is no check to confirm that the assertion
183/// originated in the component under test.
184///
185/// ### Enabling Negative Testing {#bsls_asserttest-enabling-negative-testing}
186///
187///
188/// In order to enable the negative testing facility, you must:
189/// * `#include` this component header, `bsls_asserttest.h`.
190/// * Supply an implementation of an `ASSERT` macro in your test driver.
191/// * Register `bsls::AssertTest::failTestDriver` as the active
192/// assertion-failure handler (preferably with an instance of
193/// `AssertTestHandlerGuard`).
194///
195/// ### Validating Disabled Macro Statements {#bsls_asserttest-validating-disabled-macro-statements}
196///
197///
198/// An additional external macro, `BSLS_ASSERTTEST_VALIDATE_DISABLED_MACROS`,
199/// can be defined to control the compile time behavior of @ref bsls_asserttest .
200/// Enabling this macro configures all *disabled* asserttest macros to still
201/// instantiate their statements (in blocks that will not be evaluated) to be
202/// sure that the statement is still syntactically valid. This can be used to
203/// ensure tests that are rarely enabled remain syntactically valid.
204///
205/// Note: this behavior is currently always enabled and cannot be turned off.
206///
207/// ### Validating Macro Testing Levels {#bsls_asserttest-validating-macro-testing-levels}
208///
209///
210/// Another external macro, `BSLS_ASSERTTEST_CHECK_LEVEL`, can be used to add an
211/// additional check that the assertion that fails is of the same level or
212/// narrower than the macro testing the assertion. This will ensure that in all
213/// build modes where the assertion is enabled the test for that assertion will
214/// also be enabled.
215///
216/// Note that some variations of language contracts might not support the
217/// checking of levels when testing assertions, and in those cases the macro
218/// `BSLS_ASSERTTEST_CAN_CHECK_LEVELS` will not be defined.
219///
220/// ### Addtional Test Pass Macros {#bsls_asserttest-addtional-test-pass-macros}
221///
222///
223/// Seven additional `PASS` macros exist to parallel the remaining `FAIL`
224/// macros.
225/// * `BSLS_ASSERTTEST_ASSERT_SAFE_PASS`
226/// * `BSLS_ASSERTTEST_ASSERT_SAFE_PASS_RAW`
227/// * `BSLS_ASSERTTEST_ASSERT_PASS_RAW`
228/// * `BSLS_ASSERTTEST_ASSERT_OPT_PASS`
229/// * `BSLS_ASSERTTEST_ASSERT_OPT_PASS_RAW`
230/// * `BSLS_ASSERTTEST_ASSERT_INVOKE_PASS`
231/// * `BSLS_ASSERTTEST_ASSERT_INVOKE_PASS_RAW`
232/// These macros are all functionally identical to
233/// `BSLS_ASSERTTEST_ASSERT_PASS`. They exist so that `PASS` checks format
234/// consistently with the corresponding negative tests they are associated with
235/// in a test driver. See {Example 2}, below, for how this can help formatting
236/// assertion testing code.
237///
238/// ## Usage {#bsls_asserttest-usage}
239///
240///
241///
242/// ### Example 1: Testing Assertions In A Simple Vector Implementation {#bsls_asserttest-example-1-testing-assertions-in-a-simple-vector-implementation}
243///
244///
245/// First we will demonstrate how "negative testing" might be used to verify
246/// that the correct assertions are in place on `std::vector::operator[]`. We
247/// start by supplying a primitive vector-like class that offers the minimal set
248/// of operations necessary to demonstrate the test case.
249/// @code
250/// template <class T>
251/// class AssertTestVector {
252/// // This class simulates a 'std::vector' with a fixed capacity of 10
253/// // elements.
254///
255/// private:
256/// // DATA
257/// T d_data[10];
258/// int d_size;
259///
260/// public:
261/// // CREATORS
262/// AssertTestVector();
263/// // Create an empty 'AssertTestVector' object.
264///
265/// // MANIPULATORS
266/// void push_back(const T& value);
267/// // Append the specified 'value' to the back of this object. The
268/// // behavior is undefined unless this method has been called fewer
269/// // than 10 times on this object.
270///
271/// // ACCESSORS
272/// const T& operator[](int index) const;
273/// // Return a reference with non-modifiable access to the object at
274/// // the specified 'index' in this object.
275/// };
276/// @endcode
277/// Next we implement the support functions.
278/// @code
279/// template <class T>
280/// AssertTestVector<T>::AssertTestVector()
281/// : d_data()
282/// , d_size()
283/// {
284/// }
285///
286/// template<class T>
287/// void AssertTestVector<T>::push_back(const T& value)
288/// {
289/// BSLS_ASSERT_SAFE(d_size < 10);
290///
291/// d_data[d_size] = value;
292/// ++d_size;
293/// }
294/// @endcode
295/// We conclude the definition of this support type with the implementation of
296/// the `operator[]` overload. Note the use of `BSLS_ASSERT_SAFE`, which is
297/// typical for function template definitions and inline function definitions.
298/// It is most appropriate in this case as the cost of evaluating each test is
299/// significant (> ~20%) compared to simply returning a reference to the result.
300/// @code
301/// template <class T>
302/// const T& AssertTestVector<T>::operator[](int index) const
303/// {
304/// BSLS_ASSERT_SAFE(0 <= index);
305/// BSLS_ASSERT_SAFE( index < d_size);
306///
307/// return d_data[index];
308/// }
309/// @endcode
310/// Finally, we can write the function to test that the `BSLS_ASSERT_SAFE`
311/// macros placed in `operator[]` work as expected. We want to validate that
312/// the assertions trigger when the function preconditions are violated; we
313/// further want to validate that the assertion macros are enabled in the build
314/// modes that we expect. We start by defining some macro aliases that will
315/// make the test driver more readable. These macro aliases are a common
316/// feature of test drivers.
317/// @code
318/// #define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR)
319/// #define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR)
320/// #define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR)
321/// #define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR)
322/// @endcode
323/// Then we implement the test function itself. Note that we check that
324/// exceptions are available in the current build mode, as the test macros rely
325/// on the exception facility in order to return their diagnostic results. If
326/// exceptions are not available, there is nothing for a "negative test" to do.
327/// We also avoid warnings from UBSAN builds.
328/// @code
329/// void testVectorArrayAccess()
330/// {
331/// #if defined(BDE_BUILD_TARGET_EXC) && !defined(BDE_BUILD_TARGET_UBSAN)
332/// bsls::AssertTestHandlerGuard g;
333///
334/// AssertTestVector<void *> mA; const AssertTestVector<void *> &A = mA;
335///
336/// ASSERT_SAFE_FAIL(mA[-1]);
337/// ASSERT_SAFE_FAIL(mA[ 0]);
338/// ASSERT_SAFE_FAIL(mA[ 1]);
339///
340/// ASSERT_SAFE_FAIL( A[-1]);
341/// ASSERT_SAFE_FAIL( A[ 0]);
342/// ASSERT_SAFE_FAIL( A[ 1]);
343///
344/// mA.push_back(0); // increase the length to one
345///
346/// ASSERT_SAFE_FAIL(mA[-1]);
347/// ASSERT_PASS (mA[ 0]);
348/// ASSERT_SAFE_FAIL(mA[ 1]);
349///
350/// ASSERT_SAFE_FAIL( A[-1]);
351/// ASSERT_PASS ( A[ 0]);
352/// ASSERT_SAFE_FAIL( A[ 1]);
353/// #else // defined(BDE_BUILD_TARGET_EXC) && !defined(BDE_BUILD_TARGET_UBSAN)
354/// @endcode
355/// If exceptions are not available, then we write a diagnostic message to the
356/// console alerting the user that this part of the test has not run, without
357/// failing the test.
358/// @code
359/// if (globalVerbose) printf(
360/// "\tDISABLED in this (non-exception) build mode.\n");
361///
362/// #endif // defined(BDE_BUILD_TARGET_EXC) && !defined(BDE_BUILD_TARGET_UBSAN)
363/// }
364/// @endcode
365///
366/// ### Example 2: Using PASS macros to help with formatting {#bsls_asserttest-example-2-using-pass-macros-to-help-with-formatting}
367///
368///
369/// When testing the various inputs to a function to be sure that some trigger
370/// an assertion and some are in contract, it often helps to align the testing
371/// macros so that the various arguments are easily readable in relation to one
372/// another. We start by defining additional macro aliases to match the
373/// existing aliases already defined:
374/// @code
375/// #define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR)
376/// #define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR)
377/// @endcode
378/// Considering the function `testVectorArrayAccess` from {Example 1}, we could
379/// instead implement it without padded white space by using `ASSERT_SAFE_PASS`
380/// to replace `ASSERT_PASS`, matching the existing `ASSERT_SAFE_FAIL` tests,
381/// like this:
382/// @code
383/// void testVectorArrayAccess2()
384/// {
385/// #if defined(BDE_BUILD_TARGET_EXC) && !defined(BDE_BUILD_TARGET_UBSAN)
386/// bsls::AssertTestHandlerGuard g;
387///
388/// AssertTestVector<void *> mA; const AssertTestVector<void *> &A = mA;
389///
390/// ASSERT_SAFE_FAIL(mA[-1]);
391/// ASSERT_SAFE_FAIL(mA[ 0]);
392/// ASSERT_SAFE_FAIL(mA[ 1]);
393///
394/// ASSERT_SAFE_FAIL( A[-1]);
395/// ASSERT_SAFE_FAIL( A[ 0]);
396/// ASSERT_SAFE_FAIL( A[ 1]);
397///
398/// mA.push_back(0); // increase the length to one
399///
400/// ASSERT_SAFE_FAIL(mA[-1]);
401/// ASSERT_SAFE_PASS(mA[ 0]);
402/// ASSERT_SAFE_FAIL(mA[ 1]);
403///
404/// ASSERT_SAFE_FAIL( A[-1]);
405/// ASSERT_SAFE_PASS( A[ 0]);
406/// ASSERT_SAFE_FAIL( A[ 1]);
407/// #endif // defined(BDE_BUILD_TARGET_EXC) && !defined(BDE_BUILD_TARGET_UBSAN)
408/// }
409/// @endcode
410/// @}
411/** @} */
412/** @} */
413
414/** @addtogroup bsl
415 * @{
416 */
417/** @addtogroup bsls
418 * @{
419 */
420/** @addtogroup bsls_asserttest
421 * @{
422 */
423
424#include <bsls_annotation.h>
425#include <bsls_assert.h>
427#include <bsls_buildtarget.h>
429#include <bsls_platform.h>
430#include <bsls_review.h>
431
432 // =============================
433 // Checks for Pre-Defined macros
434 // =============================
435
436#if defined (ASSERTTEST_ASSERT_ACTIVE_FLAG)
437#error ASSERTTEST_ASSERT_ACTIVE_FLAG is alread defined!
438#endif
439
440#if defined (ASSERTTEST_ASSERT_OPT_ACTIVE_FLAG)
441#error ASSERTTEST_ASSERT_OPT_ACTIVE_FLAG is alread defined!
442#endif
443
444#if defined (ASSERTTEST_ASSERT_SAFE_ACTIVE_FLAG)
445#error ASSERTTEST_ASSERT_SAFE_ACTIVE_FLAG is alread defined!
446#endif
447
448#if defined (ASSERTTEST_SAFE_2_BUILD_FLAG)
449#error ASSERTTEST_SAFE_2_BUILD_FLAG is alread defined!
450#endif
451
452#if defined (ASSERTTEST_IS_ACTIVE)
453#error ASSERTTEST_IS_ACTIVE is alread defined!
454#endif
455
456#if defined (ASSERTTEST_ASSERT_FAIL)
457#error ASSERTTEST_ASSERT_FAIL is alread defined!
458#endif
459
460#if defined (ASSERTTEST_ASSERT_FAIL_RAW)
461#error ASSERTTEST_ASSERT_FAIL_RAW is alread defined!
462#endif
463
464#if defined (ASSERTTEST_ASSERT_INVOKE_FAIL)
465#error ASSERTTEST_ASSERT_INVOKE_FAIL is alread defined!
466#endif
467
468#if defined (ASSERTTEST_ASSERT_INVOKE_FAIL_RAW)
469#error ASSERTTEST_ASSERT_INVOKE_FAIL_RAW is alread defined!
470#endif
471
472#if defined (ASSERTTEST_ASSERT_OPT_FAIL)
473#error ASSERTTEST_ASSERT_OPT_FAIL is alread defined!
474#endif
475
476#if defined (ASSERTTEST_ASSERT_OPT_FAIL_RAW)
477#error ASSERTTEST_ASSERT_OPT_FAIL_RAW is alread defined!
478#endif
479
480#if defined (ASSERTTEST_ASSERT_SAFE_FAIL)
481#error ASSERTTEST_ASSERT_SAFE_FAIL is alread defined!
482#endif
483
484#if defined (ASSERTTEST_ASSERT_SAFE_FAIL_RAW)
485#error ASSERTTEST_ASSERT_SAFE_FAIL_RAW is alread defined!
486#endif
487
488#if defined (ASSERTTEST_ASSERT_INVOKE_PASS)
489#error ASSERTTEST_ASSERT_INVOKE_PASS is alread defined!
490#endif
491
492#if defined (ASSERTTEST_ASSERT_INVOKE_PASS_RAW)
493#error ASSERTTEST_ASSERT_INVOKE_PASS_RAW is alread defined!
494#endif
495
496#if defined (ASSERTTEST_ASSERT_OPT_PASS)
497#error ASSERTTEST_ASSERT_OPT_PASS is alread defined!
498#endif
499
500#if defined (ASSERTTEST_ASSERT_OPT_PASS_RAW)
501#error ASSERTTEST_ASSERT_OPT_PASS_RAW is alread defined!
502#endif
503
504#if defined (ASSERTTEST_ASSERT_PASS)
505#error ASSERTTEST_ASSERT_PASS is alread defined!
506#endif
507
508#if defined (ASSERTTEST_ASSERT_PASS_RAW)
509#error ASSERTTEST_ASSERT_PASS_RAW is alread defined!
510#endif
511
512#if defined (ASSERTTEST_ASSERT_SAFE_PASS)
513#error ASSERTTEST_ASSERT_SAFE_PASS is alread defined!
514#endif
515
516#if defined (ASSERTTEST_ASSERT_SAFE_PASS_RAW)
517#error ASSERTTEST_ASSERT_SAFE_PASS_RAW is alread defined!
518#endif
519
520#if defined (ASSERTTEST_BRUTE_FORCE_IMP)
521#error ASSERTTEST_BRUTE_FORCE_IMP is alread defined!
522#endif
523
524#if defined (ASSERTTEST_BRUTE_FORCE_IMP_RAW)
525#error ASSERTTEST_BRUTE_FORCE_IMP_RAW is alread defined!
526#endif
527
528#if defined (ASSERTTEST_CAN_CHECK_LEVELS)
529#error ASSERTTEST_CAN_CHECK_LEVELS is alread defined!
530#endif
531
532#if defined (ASSERTTEST_CHECK_LEVEL_ARG)
533#error ASSERTTEST_CHECK_LEVEL_ARG is alread defined!
534#endif
535
536#if defined (ASSERTTEST_DISABLED_IMP)
537#error ASSERTTEST_DISABLED_IMP is alread defined!
538#endif
539
540 // ==============================
541 // ASSERTTEST_*_BUILD_FLAG macros
542 // ==============================
543
544#ifdef BDE_BUILD_TARGET_SAFE_2
545 #define BSLS_ASSERTTEST_SAFE_2_BUILD_FLAG true
546#else
547 #define BSLS_ASSERTTEST_SAFE_2_BUILD_FLAG false
548#endif
549
550#ifdef BSLS_ASSERT_SAFE_IS_ACTIVE
551 #define BSLS_ASSERTTEST_ASSERT_SAFE_ACTIVE_FLAG true
552#else
553 #define BSLS_ASSERTTEST_ASSERT_SAFE_ACTIVE_FLAG false
554#endif
555
556#ifdef BSLS_ASSERT_IS_ACTIVE
557 #define BSLS_ASSERTTEST_ASSERT_ACTIVE_FLAG true
558#else
559 #define BSLS_ASSERTTEST_ASSERT_ACTIVE_FLAG false
560#endif
561
562#ifdef BSLS_ASSERT_OPT_IS_ACTIVE
563 #define BSLS_ASSERTTEST_ASSERT_OPT_ACTIVE_FLAG true
564#else
565 #define BSLS_ASSERTTEST_ASSERT_OPT_ACTIVE_FLAG false
566#endif
567
568#define BSLS_ASSERTTEST_IS_ACTIVE(TYPE) ( \
569 ( '\0' == TYPE[1] \
570 || BSLS_ASSERTTEST_SAFE_2_BUILD_FLAG \
571 ) \
572 && \
573 ( ('S' == TYPE[0] && BSLS_ASSERTTEST_ASSERT_SAFE_ACTIVE_FLAG) \
574 || ('A' == TYPE[0] && BSLS_ASSERTTEST_ASSERT_ACTIVE_FLAG) \
575 || ('O' == TYPE[0] && BSLS_ASSERTTEST_ASSERT_OPT_ACTIVE_FLAG) \
576 ) \
577)
578
579#if !defined(BSLS_ASSERT_USE_CONTRACTS)
580 #define BSLS_ASSERTTEST_CAN_CHECK_LEVELS
581#else
582 // Determine if the current use of language contracts can support level
583 // checking. As of now, none can.
584#endif
585
586#ifdef BSLS_ASSERTTEST_CHECK_LEVEL
587 #define BSLS_ASSERTTEST_CHECK_LEVEL_ARG true
588#else
589 #define BSLS_ASSERTTEST_CHECK_LEVEL_ARG false
590#endif
591
592#ifdef BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_CLANG
593#define BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) \
594 _Pragma("GCC diagnostic push") \
595 _Pragma("GCC diagnostic ignored \"-Wunused-comparison\"") \
596 _Pragma("GCC diagnostic ignored \"-Wunused-value\"") \
597 STATEMENT_UNDER_TEST; \
598 _Pragma("GCC diagnostic pop")
599#else
600#define BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) \
601 STATEMENT_UNDER_TEST;
602#endif
603
604#define BSLS_ASSERTTEST_BRUTE_FORCE_IMP(RESULT, LVL, STATEMENT_UNDER_TEST) { \
605 try { \
606 BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) \
607 \
608 ASSERT(BloombergLP::bsls::AssertTest::tryProbe(RESULT, LVL)); \
609 } \
610 catch (const BloombergLP::bsls::AssertTestException& e) { \
611 ASSERT(BloombergLP::bsls::AssertTest::catchProbe( \
612 RESULT, \
613 BSLS_ASSERTTEST_CHECK_LEVEL_ARG, \
614 LVL, \
615 e, \
616 __FILE__)); \
617 } \
618}
619
620#define BSLS_ASSERTTEST_VALIDATE_DISABLED_MACROS
621#ifdef BSLS_ASSERTTEST_VALIDATE_DISABLED_MACROS
622 #define BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST) \
623 while (false) do { \
624 BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) \
625 } while (false);
626#else
627 #define BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST) \
628 do {} while (false);
629#endif
630
631#if !defined(BDE_BUILD_TARGET_EXC)
632// In non-exception enabled builds there is no way to safely use the
633// ASSERT_FAIL macros as they require installing an assert-handler that throws
634// a specific exception. ASSERT_FAIL negative tests require calling a method
635// under test with out-of-contract values; running those tests without a
636// functioning assert-handler would trigger undefined behavior with no
637// protection so we choose to simple not execute the test calls that are
638// designed to fail by expanding the test macros to an empty statement, '{ }'.
639// All of the ASSERT_PASS macros are expanded however, as such tests call
640// methods with in-contract values, and they may still be needed to guarantee
641// stateful side-effects required by the test-driver.
642
643#define BSLS_ASSERTTEST_ASSERT_SAFE_PASS(STATEMENT_UNDER_TEST) \
644 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
645
646#define BSLS_ASSERTTEST_ASSERT_PASS(STATEMENT_UNDER_TEST) \
647 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
648
649#define BSLS_ASSERTTEST_ASSERT_OPT_PASS(STATEMENT_UNDER_TEST) \
650 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
651
652#define BSLS_ASSERTTEST_ASSERT_INVOKE_PASS(STATEMENT_UNDER_TEST) \
653 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
654
655#define BSLS_ASSERTTEST_ASSERT_SAFE_PASS_RAW(STATEMENT_UNDER_TEST) \
656 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
657
658#define BSLS_ASSERTTEST_ASSERT_PASS_RAW(STATEMENT_UNDER_TEST) \
659 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
660
661#define BSLS_ASSERTTEST_ASSERT_OPT_PASS_RAW(STATEMENT_UNDER_TEST) \
662 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
663
664#define BSLS_ASSERTTEST_ASSERT_INVOKE_PASS_RAW(STATEMENT_UNDER_TEST) \
665 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
666
667#define BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(STATEMENT_UNDER_TEST) \
668 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
669
670#define BSLS_ASSERTTEST_ASSERT_FAIL(STATEMENT_UNDER_TEST) \
671 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
672
673#define BSLS_ASSERTTEST_ASSERT_OPT_FAIL(STATEMENT_UNDER_TEST) \
674 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
675
676#define BSLS_ASSERTTEST_ASSERT_SAFE_FAIL_RAW(STATEMENT_UNDER_TEST) \
677 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
678
679#define BSLS_ASSERTTEST_ASSERT_FAIL_RAW(STATEMENT_UNDER_TEST) \
680 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
681
682#define BSLS_ASSERTTEST_ASSERT_OPT_FAIL_RAW(STATEMENT_UNDER_TEST) \
683 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
684
685#define BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL(STATEMENT_UNDER_TEST) \
686 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
687
688#define BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL_RAW(STATEMENT_UNDER_TEST) \
689 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
690
691#else // defined BDE_BUILD_TARGET_EXC
692
693// The following macros are not expanded on the Microsoft compiler to avoid
694// internal compiler errors in optimized builds, which are the result of
695// attempts to optimize many try/catch blocks in large switch statements. Note
696// that the resulting test driver is just as thorough, but will report failure
697// of a buggy library by simply crashing, rather than capturing and reporting
698// the specific error detected.
699#if (defined(BSLS_PLATFORM_CMP_MSVC) && defined(BDE_BUILD_TARGET_OPT))
700#define BSLS_ASSERTTEST_ASSERT_SAFE_PASS(STATEMENT_UNDER_TEST) \
701 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
702
703#define BSLS_ASSERTTEST_ASSERT_PASS(STATEMENT_UNDER_TEST) \
704 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
705
706#define BSLS_ASSERTTEST_ASSERT_OPT_PASS(STATEMENT_UNDER_TEST) \
707 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
708
709#define BSLS_ASSERTTEST_ASSERT_INVOKE_PASS(STATEMENT_UNDER_TEST) \
710 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
711#else // optimized msvc
712#define BSLS_ASSERTTEST_ASSERT_SAFE_PASS(STATEMENT_UNDER_TEST) \
713 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('P', 'S', STATEMENT_UNDER_TEST)
714
715#define BSLS_ASSERTTEST_ASSERT_PASS(STATEMENT_UNDER_TEST) \
716 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('P', 'A', STATEMENT_UNDER_TEST)
717
718#define BSLS_ASSERTTEST_ASSERT_OPT_PASS(STATEMENT_UNDER_TEST) \
719 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('P', 'O', STATEMENT_UNDER_TEST)
720
721#define BSLS_ASSERTTEST_ASSERT_INVOKE_PASS(STATEMENT_UNDER_TEST) \
722 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('P', 'I', STATEMENT_UNDER_TEST)
723#endif // not (msvc and optimized)
724
725#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
726# define BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(STATEMENT_UNDER_TEST) \
727 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('F', 'S', STATEMENT_UNDER_TEST)
728#else
729# define BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(STATEMENT_UNDER_TEST) \
730 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
731#endif
732
733#if defined(BSLS_ASSERT_IS_ACTIVE)
734 #define BSLS_ASSERTTEST_ASSERT_FAIL(STATEMENT_UNDER_TEST) \
735 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('F', 'A', STATEMENT_UNDER_TEST)
736#else
737 #define BSLS_ASSERTTEST_ASSERT_FAIL(STATEMENT_UNDER_TEST) \
738 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
739#endif
740
741#if defined(BSLS_ASSERT_OPT_IS_ACTIVE)
742 #define BSLS_ASSERTTEST_ASSERT_OPT_FAIL(STATEMENT_UNDER_TEST) \
743 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('F', 'O', STATEMENT_UNDER_TEST)
744#else
745 #define BSLS_ASSERTTEST_ASSERT_OPT_FAIL(STATEMENT_UNDER_TEST) \
746 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
747#endif
748
749#define BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL(STATEMENT_UNDER_TEST) \
750 BSLS_ASSERTTEST_BRUTE_FORCE_IMP('F', 'I', STATEMENT_UNDER_TEST)
751
752#define BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW(RESULT, \
753 LVL, \
754 STATEMENT_UNDER_TEST) { \
755 try { \
756 BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) \
757 \
758 ASSERT(BloombergLP::bsls::AssertTest::tryProbeRaw(RESULT, LVL)); \
759 } \
760 catch (const BloombergLP::bsls::AssertTestException& e) { \
761 ASSERT(BloombergLP::bsls::AssertTest::catchProbeRaw( \
762 RESULT, \
763 BSLS_ASSERTTEST_CHECK_LEVEL_ARG, \
764 LVL, \
765 e)); \
766 } \
767}
768
769#if defined(BSLS_PLATFORM_CMP_MSVC) && defined(BDE_BUILD_TARGET_OPT)
770// The following MSVC-specific work-around avoids compilation issues with MSVC
771// optimized builds.
772
773#define BSLS_ASSERTTEST_ASSERT_SAFE_PASS_RAW(STATEMENT_UNDER_TEST) \
774 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
775
776#define BSLS_ASSERTTEST_ASSERT_PASS_RAW(STATEMENT_UNDER_TEST) \
777 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
778
779#define BSLS_ASSERTTEST_ASSERT_OPT_PASS_RAW(STATEMENT_UNDER_TEST) \
780 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
781
782#define BSLS_ASSERTTEST_ASSERT_INVOKE_PASS_RAW(STATEMENT_UNDER_TEST) \
783 { BSLS_ASSERTTEST_EVAL_STATEMENT_IMP(STATEMENT_UNDER_TEST) }
784#else
785#define BSLS_ASSERTTEST_ASSERT_SAFE_PASS_RAW(STATEMENT_UNDER_TEST) \
786 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('P', 'S', STATEMENT_UNDER_TEST)
787
788#define BSLS_ASSERTTEST_ASSERT_PASS_RAW(STATEMENT_UNDER_TEST) \
789 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('P', 'A', STATEMENT_UNDER_TEST)
790
791#define BSLS_ASSERTTEST_ASSERT_OPT_PASS_RAW(STATEMENT_UNDER_TEST) \
792 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('P', 'O', STATEMENT_UNDER_TEST)
793
794#define BSLS_ASSERTTEST_ASSERT_INVOKE_PASS_RAW(STATEMENT_UNDER_TEST) \
795 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('P', 'I', STATEMENT_UNDER_TEST)
796#endif
797
798#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
799 #define BSLS_ASSERTTEST_ASSERT_SAFE_FAIL_RAW(STATEMENT_UNDER_TEST) \
800 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('F', 'S', STATEMENT_UNDER_TEST)
801#else
802 #define BSLS_ASSERTTEST_ASSERT_SAFE_FAIL_RAW(STATEMENT_UNDER_TEST) \
803 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
804#endif
805
806#if defined(BSLS_ASSERT_IS_ACTIVE)
807 #define BSLS_ASSERTTEST_ASSERT_FAIL_RAW(STATEMENT_UNDER_TEST) \
808 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('F', 'A', STATEMENT_UNDER_TEST)
809#else
810 #define BSLS_ASSERTTEST_ASSERT_FAIL_RAW(STATEMENT_UNDER_TEST) \
811 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
812#endif
813
814#if defined(BSLS_ASSERT_OPT_IS_ACTIVE)
815 #define BSLS_ASSERTTEST_ASSERT_OPT_FAIL_RAW(STATEMENT_UNDER_TEST) \
816 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('F', 'O', STATEMENT_UNDER_TEST)
817#else
818 #define BSLS_ASSERTTEST_ASSERT_OPT_FAIL_RAW(STATEMENT_UNDER_TEST) \
819 BSLS_ASSERTTEST_DISABLED_IMP(STATEMENT_UNDER_TEST)
820#endif
821
822#define BSLS_ASSERTTEST_ASSERT_INVOKE_FAIL_RAW(STATEMENT_UNDER_TEST) \
823 BSLS_ASSERTTEST_BRUTE_FORCE_IMP_RAW('F', 'I', STATEMENT_UNDER_TEST)
824
825#endif // BDE_BUILD_TARGET_EXC
826
827// Provide a deeper "include-guard" to protect against repeated inclusion by
828// the test driver for this component. This is necessary because, in order to
829// test the macros and pre-processor logic that constitute key parts of this
830// component, this header must be included multiple times by the test driver,
831// which will deliberately '#undef' the main include-guard to achieve this
832// effect. The deeper include-guard protects the non-macro parts of this
833// header that cannot be defined more than once.
834#ifndef BSLS_ASSERTTEST_RECURSIVELY_INCLUDED_TESTDRIVER_GUARD
835#define BSLS_ASSERTTEST_RECURSIVELY_INCLUDED_TESTDRIVER_GUARD
836
837
838namespace bsls {
839
840 // ================
841 // class AssertTest
842 // ================
843
844/// This utility `struct` provides a suite of methods designed for use in
845/// conjunction with preprocessor macros during the negative testing of
846/// defensive checks using the facilities provided by the @ref bsls_assert
847/// component. Unlike usual BDE functionality methods in this `struct`
848/// provide wide contracts because they need to function without assertion
849/// failures during testing, under unforeseen circumstances.
850///
851/// See @ref bsls_asserttest
853
854 // CLASS METHODS
855
856 // Test Specification Validation
857
858 /// Return `true` if the specified `specString` represents a valid
859 /// textual description of an assertion build type, and `false`
860 /// otherwise. `specString` is valid if it refers to a null-terminated
861 /// character string of length either 1 or 2, where the first character
862 /// is an (UPPERCASE) `S`, `A`, `O`, or `I`, and the second character, if present, is the numeral `2`.
863 ///
864 /// \note Note that `S`, `A`, `O`, and `I`
865 /// are intended to represent the respective assertion types
866 /// `BSLS_ASSERT_SAFE`, `BSLS_ASSERT`, `BSLS_ASSERT_OPT`, and
867 /// `BSLS_ASSERT_INVOKE`, and the optional `2` is intended to indicate
868 /// that the component (and program as a whole) was built with `BDE_BUILD_TARGET_SAFE_2` defined.
869 ///
870 /// \pre The behavior is undefined unless
871 /// `specString` points to a null terminated string (C string).
872 static bool isValidAssertBuild(const char *specString);
873
874 /// Return `true` if the specified `specChar` represents a valid
875 /// description of the expected result, and `false` otherwise.
876 /// `specChar` is valid if it is either an (UPPERCASE) `P` (for Pass) or `F` (for Fail).
877 ///
878 /// \note Note that `P` is intended to represent the
879 /// expectation that the function under test will "pass" by satisfying
880 /// all preconditions, including the specific one guarded by the
881 /// assertion under test, while an `F` is intended to indicate the
882 /// expectation that the specific assertion under test will "fail"
883 /// (thereby triggering a call to the currently-installed
884 /// assertion-failure handler).
885 static bool isValidExpected(char specChar);
886
887 /// Return `true` if the specified `specChar` represents a valid
888 /// description of the expected assert level, and `false` otherwise.
889 /// `specChar` is valid if it is either a `O` (for `OPT`), `S` (for
890 /// `SAFE`), `A` (for `ASSERT`), or `I` (for `INVOKE`).
891 static bool isValidExpectedLevel(char specChar);
892
893 // Testing Apparatus
894
895 /// Return `true` if the specified `expectedResult` is `P` (for Pass)
896 /// and the specified `expectedLevel` is a valid level; otherwise,
897 /// return `false`. If `expectedResult` is anything other than `P` or
898 /// `F` (for Fail), this function reports the invalid `expectedResult`
899 /// value to `stdout` before returning `false`. If `expectedlevel` is
900 /// anything other than `S`, `A`, `O`, or `I`, this function reports the
901 /// invalid `expectedLevel` value to `stdout` before returning `false`.
902 static bool tryProbe(char expectedResult, char expectedLevel);
903
904 /// Return `true` if the specified `expectedResult` is `F` (for Fail),
905 /// the specified `checkLevel` flag is `false` or the `expectedLevel` is
906 /// as wide or wider than the actual assertion failure level, the
907 /// specified `caughtException` contains valid fields, and the specified
908 /// `testDriverFileName` is either null or refers to the same (valid)
909 /// component name as the filename in `caughtException`; otherwise,
910 /// return `false`. If `expectedResult`, `testDriverFileName`, or any
911 /// field of `caughtException` is invalid (i.e., an invalid filename,
912 /// null or empty expression text, or a non-positive line number), this
913 /// function reports the invalid value(s) to `stdout` before returning
914 /// `false`. If `testDriverFileName` is not null, but does not reflect
915 /// the same component name as the otherwise valid filename in
916 /// `caughtException`, this function prints a message delineating the
917 /// mismatching deduced component names to `stdout` before returning
918 /// `false`.
919 static bool catchProbe(char expectedResult,
920 bool checkLevel,
921 char expectedLevel,
922 const AssertTestException& caughtException,
923 const char *testDriverFileName);
924
925 /// Return `true` if the specified `expectedResult` is `P` (for Pass)
926 /// and the specified `expectedLevel` is a valid level; otherwise,
927 /// return `false`. If `expectedResult` is anything other than `P` or
928 /// `F` (for Fail), this function reports the invalid `expectedResult`
929 /// value to `stdout` before returning `false`. If `expectedlevel` is
930 /// anything other than `S`, `A`, `O`, or `I`, this function reports the
931 /// invalid `expectedLevel` value to `stdout` before returning `false`.
932 static bool tryProbeRaw(char expectedResult, char expectedLevel);
933
934 /// Return `true` if the specified `expectedResult` is `F` (for Fail),
935 /// the specified `checkLevel` flag is `false` or the `expectedLevel` is
936 /// as wide or wider than the actual assertion failure level, and the
937 /// specified `caughtException` contains valid fields; otherwise, return
938 /// `false`. If `expectedResult`, `expectedLevel`, or any field of
939 /// `caughtException` is invalid (i.e., an invalid filename, null or
940 /// empty expression text, or a non-positive line number), this function
941 /// reports the invalid value(s) to `stdout` before returning `false`.
942 static bool catchProbeRaw(char expectedResult,
943 bool checkLevel,
944 char expectedLevel,
945 const AssertTestException& caughtException);
946
947 // Testing Failure Handlers
948
949 /// Throw an `AssertTestException` having the pointer values `text` and
950 /// `file` and the integer `line` from the specified `violation` as its
951 /// salient attributes, provided that `BDE_BUILD_TARGET_EXC` is defined;
952 /// otherwise, log an appropriate message and abort the program (similar to `Assert::failAbort`).
953 ///
954 /// \note Note that this function is intended to
955 /// have a signature compatible with a registered assertion-failure
956 /// handler function in @ref bsls_assert .
958 static void failTestDriver(const AssertViolation &violation);
959
960 /// Throw an `AssertTestException` having the `comment`, `fileName`, and
961 /// `lineNumber` taken from the specified `violation` as its salient
962 /// attributes, provided that `BDE_BUILD_TARGET_EXC` is defined;
963 /// otherwise, log an appropriate message and abort the program (similar to `Assert::failAbort`).
964 ///
965 /// \note Note that this function is intended to
966 /// have a signature compatible with a registered assertion-failure
967 /// handler function in @ref bsls_assert .
968 static void failTestDriverByReview(const ReviewViolation &violation);
969};
970
971 // ============================
972 // class AssertTestHandlerGuard
973 // ============================
974
975/// This class provides a guard that will install and uninstall the negative
976/// testing assertion handler, `AssertTest::failTestDriver`, within the
977/// protected scope, as well as a corresponding review handler,
978/// `AssertTest::failTestDriverByReview`.
979///
980/// See @ref bsls_asserttest
982
983 // DATA
984 AssertFailureHandlerGuard d_assertGuard;
985 ReviewFailureHandlerGuard d_reviewGuard;
986
987 public:
988 // CREATORS
989
990 /// Create a `AssertTestHandlerGuard` object, installing the
991 /// `AssertTest::failTestDriver` assertion handler.
993
995 // Destroy this object and uninstall 'AssertTest::failTestDriver' as
996 // the current assertion handler.
997};
998
999
1000// ============================================================================
1001// INLINE FUNCTION DEFINITIONS
1002// ============================================================================
1003
1004
1005 // ------------------------
1006 // class AssertHandlerGuard
1007 // ------------------------
1008
1009inline
1011: d_assertGuard(&AssertTest::failTestDriver)
1012, d_reviewGuard(&AssertTest::failTestDriverByReview)
1013{
1014}
1015
1016} // close package namespace
1017
1018#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
1019// ============================================================================
1020// BACKWARD COMPATIBILITY
1021// ============================================================================
1022
1023/// This alias is defined for backward compatibility.
1025
1026/// This alias is defined for backward compatibility.
1028#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
1029
1030
1031
1032#endif // test driver internal include guard
1033
1034#endif
1035
1036// ----------------------------------------------------------------------------
1037// Copyright 2018 Bloomberg Finance L.P.
1038//
1039// Licensed under the Apache License, Version 2.0 (the "License");
1040// you may not use this file except in compliance with the License.
1041// You may obtain a copy of the License at
1042//
1043// http://www.apache.org/licenses/LICENSE-2.0
1044//
1045// Unless required by applicable law or agreed to in writing, software
1046// distributed under the License is distributed on an "AS IS" BASIS,
1047// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1048// See the License for the specific language governing permissions and
1049// limitations under the License.
1050// ----------------------------- END-OF-FILE ----------------------------------
1051
1052/** @} */
1053/** @} */
1054/** @} */
Definition bsls_assert.h:2451
Definition bsls_asserttestexception.h:156
Definition bsls_asserttest.h:981
AssertTestHandlerGuard()
Definition bsls_asserttest.h:1010
Definition bsls_assert.h:2139
Definition bsls_review.h:1310
Definition bsls_review.h:1097
#define BSLS_ANNOTATION_NORETURN
Definition bsls_annotation.h:378
bsls::AssertTest bsls_AssertTest
This alias is defined for backward compatibility.
Definition bsls_asserttest.h:1027
bsls::AssertTestHandlerGuard bsls_AssertTestHandlerGuard
This alias is defined for backward compatibility.
Definition bsls_asserttest.h:1024
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlt_iso8601util.h:707
Definition bsls_asserttest.h:852
static bool catchProbe(char expectedResult, bool checkLevel, char expectedLevel, const AssertTestException &caughtException, const char *testDriverFileName)
static bool isValidAssertBuild(const char *specString)
static bool tryProbe(char expectedResult, char expectedLevel)
static bool isValidExpected(char specChar)
static bool catchProbeRaw(char expectedResult, bool checkLevel, char expectedLevel, const AssertTestException &caughtException)
static void failTestDriverByReview(const ReviewViolation &violation)
static bool tryProbeRaw(char expectedResult, char expectedLevel)
static bool isValidExpectedLevel(char specChar)
static BSLS_ANNOTATION_NORETURN void failTestDriver(const AssertViolation &violation)