micro-test-plus 3.2.0
µTest++, a lightweight testing framework for embedded platforms
Loading...
Searching...
No Matches
micro-test-plus.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus/)
4 * Copyright (c) 2021 Liviu Ionescu.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from <https://opensource.org/licenses/MIT/>.
11 *
12 * Major parts of the code are inspired from v1.1.8 of the Boost UT project,
13 * released under the terms of the Boost Version 1.0 Software License,
14 * which can be obtained from <https://www.boost.org/LICENSE_1_0.txt>.
15 */
16
17#ifndef MICRO_TEST_PLUS_MICRO_TEST_PLUS_H_
18#define MICRO_TEST_PLUS_MICRO_TEST_PLUS_H_
19
20// ----------------------------------------------------------------------------
21
22#ifdef __cplusplus
23
24// ----------------------------------------------------------------------------
25
26#if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
27#include <micro-os-plus/config.h>
28#endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
29
30#include "reflection.h"
31#include "math.h"
32#include "type-traits.h"
33#include "literals.h"
34#include "test-suite.h"
35#include "test-runner.h"
36#include "test-reporter.h"
37#include "detail.h"
38
39// ----------------------------------------------------------------------------
40
41#if defined(__GNUC__)
42#pragma GCC diagnostic push
43#pragma GCC diagnostic ignored "-Wpadded"
44#pragma GCC diagnostic ignored "-Waggregate-return"
45#if defined(__clang__)
46#pragma clang diagnostic ignored "-Wc++98-compat"
47#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
48#pragma clang diagnostic ignored "-Wctad-maybe-unsupported"
49#endif
50#endif
51
53{
54 // --------------------------------------------------------------------------
55
56 extern test_runner runner;
57 extern test_reporter reporter;
58 extern test_suite_base* current_test_suite;
59
60 // --------------------------------------------------------------------------
61 // Public API.
62
72 void
73 initialize (int argc, char* argv[], const char* name = "Main");
74
82 [[nodiscard]] int
83 exit_code (void);
84
99 template <typename Callable_T, typename... Args_T>
100 void
101 test_case (const char* name, Callable_T&& callable, Args_T&&... arguments);
102
135 template <class Expr_T, type_traits::requires_t<
138 = 0>
139 constexpr auto
140 expect (const Expr_T& expr, const reflection::source_location& sl
142 {
143 return detail::deferred_reporter<Expr_T>{ expr, false, sl };
144 }
145
165 template <class Expr_T, type_traits::requires_t<
168 = 0>
169 constexpr auto
170 assume (const Expr_T& expr, const reflection::source_location& sl
172 {
173 return detail::deferred_reporter<Expr_T>{ expr, true, sl };
174 }
175
176 // --------------------------------------------------------------------------
177
178#if defined(__cpp_exceptions)
187 template <class Exception_T, class Callable_T>
188 [[nodiscard]] constexpr auto
189 throws (const Callable_T& func)
190 {
192 }
193
201 template <class Callable_T>
202 [[nodiscard]] constexpr auto
203 throws (const Callable_T& func)
204 {
205 return detail::throws_<Callable_T>{ func };
206 }
207
215 template <class Callable_T>
216 [[nodiscard]] constexpr auto
217 nothrow (const Callable_T& func)
218 {
219 return detail::nothrow_{ func };
220 }
221#endif
222
223 // --------------------------------------------------------------------------
224
235 template <class Lhs_T, class Rhs_T>
236 [[nodiscard]] constexpr auto
237 eq (const Lhs_T& lhs, const Rhs_T& rhs)
238 {
239 return detail::eq_{ lhs, rhs };
240 }
241
252 template <class Lhs_T, class Rhs_T>
253 [[nodiscard]] constexpr auto
254 eq (Lhs_T* lhs, Rhs_T* rhs)
255 {
256 return detail::eq_{ lhs, rhs };
257 }
258
268 template <class Lhs_T, class Rhs_T>
269 [[nodiscard]] constexpr auto
270 ne (const Lhs_T& lhs, const Rhs_T& rhs)
271 {
272 return detail::ne_{ lhs, rhs };
273 }
274
284 template <class Lhs_T, class Rhs_T>
285 [[nodiscard]] constexpr auto
286 ne (Lhs_T* lhs, Rhs_T* rhs)
287 {
288 return detail::ne_{ lhs, rhs };
289 }
290
300 template <class Lhs_T, class Rhs_T>
301 [[nodiscard]] constexpr auto
302 gt (const Lhs_T& lhs, const Rhs_T& rhs)
303 {
304 return detail::gt_{ lhs, rhs };
305 }
306
316 template <class Lhs_T, class Rhs_T>
317 [[nodiscard]] constexpr auto
318 gt (Lhs_T* lhs, Rhs_T* rhs)
319 {
320 return detail::gt_{ lhs, rhs };
321 }
322
332 template <class Lhs_T, class Rhs_T>
333 [[nodiscard]] constexpr auto
334 ge (const Lhs_T& lhs, const Rhs_T& rhs)
335 {
336 return detail::ge_{ lhs, rhs };
337 }
338
348 template <class Lhs_T, class Rhs_T>
349 [[nodiscard]] constexpr auto
350 ge (Lhs_T* lhs, Rhs_T* rhs)
351 {
352 return detail::ge_{ lhs, rhs };
353 }
354
364 template <class Lhs_T, class Rhs_T>
365 [[nodiscard]] constexpr auto
366 lt (const Lhs_T& lhs, const Rhs_T& rhs)
367 {
368 return detail::lt_{ lhs, rhs };
369 }
370
380 template <class Lhs_T, class Rhs_T>
381 [[nodiscard]] constexpr auto
382 lt (Lhs_T* lhs, Rhs_T* rhs)
383 {
384 return detail::lt_{ lhs, rhs };
385 }
386
396 template <class Lhs_T, class Rhs_T>
397 [[nodiscard]] constexpr auto
398 le (const Lhs_T& lhs, const Rhs_T& rhs)
399 {
400 return detail::le_{ lhs, rhs };
401 }
402
412 template <class Lhs_T, class Rhs_T>
413 [[nodiscard]] constexpr auto
414 le (Lhs_T* lhs, Rhs_T* rhs)
415 {
416 return detail::le_{ lhs, rhs };
417 }
418
430 template <class Expr_T>
431 [[nodiscard]] constexpr auto
432 _not (const Expr_T& expr)
433 {
434 return detail::not_{ expr };
435 }
436
450 template <class Lhs_T, class Rhs_T>
451 [[nodiscard]] constexpr auto
452 _and (const Lhs_T& lhs, const Rhs_T& rhs)
453 {
454 return detail::and_{ lhs, rhs };
455 }
456
470 template <class Lhs_T, class Rhs_T>
471 [[nodiscard]] constexpr auto
472 _or (const Lhs_T& lhs, const Rhs_T& rhs)
473 {
474 return detail::or_{ lhs, rhs };
475 }
476
480 template <class T>
481 [[nodiscard]] constexpr auto
482 mut (const T& t) noexcept -> T&
483 {
484 return const_cast<T&> (t);
485 }
486
487 // --------------------------------------------------------------------------
488
500 namespace operators
501 {
506 [[nodiscard]] constexpr auto
507 operator== (std::string_view lhs, std::string_view rhs)
508 {
509 return detail::eq_{ lhs, rhs };
510 }
511
516 [[nodiscard]] constexpr auto
517 operator!= (std::string_view lhs, std::string_view rhs)
518 {
519 return detail::ne_{ lhs, rhs };
520 }
521
526 template <class T,
528 [[nodiscard]] constexpr auto
529 operator== (T&& lhs, T&& rhs)
530 {
531 return detail::eq_{ static_cast<T&&> (lhs), static_cast<T&&> (rhs) };
532 }
533
538 template <class T,
540 [[nodiscard]] constexpr auto
541 operator!= (T&& lhs, T&& rhs)
542 {
543 return detail::ne_{ static_cast<T&&> (lhs), static_cast<T&&> (rhs) };
544 }
545
551 template <class Lhs_T, class Rhs_T,
554 = 0>
555 [[nodiscard]] constexpr auto
556 operator== (const Lhs_T& lhs, const Rhs_T& rhs)
557 {
558 return detail::eq_{ lhs, rhs };
559 }
560
566 template <class Lhs_T, class Rhs_T,
569 = 0>
570 [[nodiscard]] constexpr auto
571 operator!= (const Lhs_T& lhs, const Rhs_T& rhs)
572 {
573 return detail::ne_{ lhs, rhs };
574 }
575
581 template <class Lhs_T, class Rhs_T,
584 = 0>
585 [[nodiscard]] constexpr auto
586 operator> (const Lhs_T& lhs, const Rhs_T& rhs)
587 {
588 return detail::gt_{ lhs, rhs };
589 }
590
596 template <class Lhs_T, class Rhs_T,
599 = 0>
600 [[nodiscard]] constexpr auto
601 operator>= (const Lhs_T& lhs, const Rhs_T& rhs)
602 {
603 return detail::ge_{ lhs, rhs };
604 }
605
611 template <class Lhs_T, class Rhs_T,
614 = 0>
615 [[nodiscard]] constexpr auto
616 operator< (const Lhs_T& lhs, const Rhs_T& rhs)
617 {
618 return detail::lt_{ lhs, rhs };
619 }
620
626 template <class Lhs_T, class Rhs_T,
629 = 0>
630 [[nodiscard]] constexpr auto
631 operator<= (const Lhs_T& lhs, const Rhs_T& rhs)
632 {
633 return detail::le_{ lhs, rhs };
634 }
635
641 template <class Lhs_T, class Rhs_T,
644 = 0>
645 [[nodiscard]] constexpr auto
646 operator and (const Lhs_T& lhs, const Rhs_T& rhs)
647 {
648 return detail::and_{ lhs, rhs };
649 }
650
656 template <class Lhs_T, class Rhs_T,
659 = 0>
660 [[nodiscard]] constexpr auto
661 operator or (const Lhs_T& lhs, const Rhs_T& rhs)
662 {
663 return detail::or_{ lhs, rhs };
664 }
665
671 template <class T, type_traits::requires_t<type_traits::is_op_v<T>> = 0>
672 [[nodiscard]] constexpr auto
673 operator not(const T& t)
674 {
675 return detail::not_{ t };
676 }
677 } // namespace operators
678
679 namespace utility
680 {
688 [[nodiscard]] bool
689 is_match (std::string_view input, std::string_view pattern);
690
700 template <class T, class Delim_T>
701 [[nodiscard]] auto
702 split (T input, Delim_T delim) -> std::vector<T>;
703
704 } // namespace utility
705
706 // --------------------------------------------------------------------------
707} // namespace micro_os_plus::micro_test_plus
708
709#if defined(__GNUC__)
710#pragma GCC diagnostic pop
711#endif
712
713// ----------------------------------------------------------------------------
714
715#endif // __cplusplus
716
717// ===== Inline & template implementations ====================================
718
720
721// All other inlines.
722#include "inlines.h"
723
724// ----------------------------------------------------------------------------
725
726#endif // MICRO_TEST_PLUS_MICRO_TEST_PLUS_H_
727
728// ----------------------------------------------------------------------------
Class template for a deferred reporter specific to an expression.
Definition detail.h:736
Local implementation of the std::source_location.
Definition reflection.h:58
static constexpr auto current(const char *file="unknown", int line={}) noexcept
Definition reflection.h:61
constexpr auto assume(const Expr_T &expr, const reflection::source_location &sl=reflection::source_location::current())
Check a condition and, if false, abort.
constexpr auto nothrow(const Callable_T &func)
Check if a callable doesn't throw an exception.
constexpr auto expect(const Expr_T &expr, const reflection::source_location &sl=reflection::source_location::current())
Evaluate a generic condition and report the results.
constexpr auto le(const Lhs_T &lhs, const Rhs_T &rhs)
Generic less than or equal comparator.
constexpr auto ge(const Lhs_T &lhs, const Rhs_T &rhs)
Generic greater than or equal comparator.
constexpr auto ne(const Lhs_T &lhs, const Rhs_T &rhs)
Generic non-equality comparator.
constexpr auto lt(const Lhs_T &lhs, const Rhs_T &rhs)
Generic less than comparator.
constexpr auto gt(const Lhs_T &lhs, const Rhs_T &rhs)
Generic greater than comparator.
constexpr auto eq(const Lhs_T &lhs, const Rhs_T &rhs)
Generic equality comparator. Matches any non-pointer type.
int exit_code(void)
Complete the test and return the exit code.
void initialize(int argc, char *argv[], const char *name="Main")
Initialize the test framework.
constexpr auto _and(const Lhs_T &lhs, const Rhs_T &rhs)
Generic logical and.
constexpr auto _or(const Lhs_T &lhs, const Rhs_T &rhs)
Generic logical or.
constexpr auto _not(const Expr_T &expr)
Generic logical not.
constexpr auto operator>=(const Lhs_T &lhs, const Rhs_T &rhs)
Greater than or equal operator. It matches only if at least one operand is of local type (derived fro...
constexpr auto operator<=(const Lhs_T &lhs, const Rhs_T &rhs)
Less than or equal operator. It matches only if at least one operand is of local type (derived from l...
constexpr auto operator>(const Lhs_T &lhs, const Rhs_T &rhs)
Greater than operator. It matches only if at least one operand is of local type (derived from local o...
constexpr auto operator<(const Lhs_T &lhs, const Rhs_T &rhs)
Less than operator. It matches only if at least one operand is of local type (derived from local op).
constexpr auto operator!=(std::string_view lhs, std::string_view rhs)
Non-equality operator for string_view objects.
constexpr auto operator==(std::string_view lhs, std::string_view rhs)
Equality operator for string_view objects.
void test_case(const char *name, Callable_T &&callable, Args_T &&... arguments)
Define and execute a test case.
Definition inlines.h:87
auto split(T input, Delim_T delim) -> std::vector< T >
Split a string into a vector of sub-strings.
Definition inlines.h:169
bool is_match(std::string_view input, std::string_view pattern)
Check if a string matches a pattern.
typename requires_< Cond >::type requires_t
constexpr auto mut(const T &t) noexcept -> T &
Generic mutator, to remove const from any type.
Greater than or equal comparator.
Definition detail.h:322
Less than or equal comparator.
Definition detail.h:439
Operator to check if the expression does not throw any exception.
Definition detail.h:666
Operator to check if the expression throws a specific exception.
Definition detail.h:600