micro-test-plus 3.2.2
The µTest++ Testing Framework
Loading...
Searching...
No Matches
micro-test-plus.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2021 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 *
11 * Major parts of the code are inspired from v1.1.8 of the Boost UT project,
12 * released under the terms of the Boost Version 1.0 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16#ifndef MICRO_TEST_PLUS_MICRO_TEST_PLUS_H_
17#define MICRO_TEST_PLUS_MICRO_TEST_PLUS_H_
18
19// ----------------------------------------------------------------------------
20
21#ifdef __cplusplus
22
23// ----------------------------------------------------------------------------
24
25#if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
26#include <micro-os-plus/config.h>
27#endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
28
29#include "reflection.h"
30#include "math.h"
31#include "type-traits.h"
32#include "literals.h"
33#include "test-suite.h"
34#include "test-runner.h"
35#include "test-reporter.h"
36#include "detail.h"
37
38// ----------------------------------------------------------------------------
39
40#if defined(__GNUC__)
41#pragma GCC diagnostic push
42#pragma GCC diagnostic ignored "-Wpadded"
43#pragma GCC diagnostic ignored "-Waggregate-return"
44#if defined(__clang__)
45#pragma clang diagnostic ignored "-Wc++98-compat"
46#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
47#pragma clang diagnostic ignored "-Wctad-maybe-unsupported"
48#endif
49#endif
50
52{
53 // --------------------------------------------------------------------------
54
55 extern test_runner runner;
58
59 // --------------------------------------------------------------------------
60 // Public API.
61
71 void
72 initialize (int argc, char* argv[], const char* name = "Main");
73
81 [[nodiscard]] int
82 exit_code (void);
83
98 template <typename Callable_T, typename... Args_T>
99 void
100 test_case (const char* name, Callable_T&& callable, Args_T&&... arguments);
101
134 template <class Expr_T, type_traits::requires_t<
137 = 0>
138 constexpr auto
139 expect (const Expr_T& expr, const reflection::source_location& sl
141 {
142 return detail::deferred_reporter<Expr_T>{ expr, false, sl };
143 }
144
164 template <class Expr_T, type_traits::requires_t<
167 = 0>
168 constexpr auto
169 assume (const Expr_T& expr, const reflection::source_location& sl
171 {
172 return detail::deferred_reporter<Expr_T>{ expr, true, sl };
173 }
174
175 // --------------------------------------------------------------------------
176
177#if defined(__cpp_exceptions)
186 template <class Exception_T, class Callable_T>
187 [[nodiscard]] constexpr auto
188 throws (const Callable_T& func)
189 {
191 }
192
200 template <class Callable_T>
201 [[nodiscard]] constexpr auto
202 throws (const Callable_T& func)
203 {
204 return detail::throws_<Callable_T>{ func };
205 }
206
214 template <class Callable_T>
215 [[nodiscard]] constexpr auto
216 nothrow (const Callable_T& func)
217 {
218 return detail::nothrow_{ func };
219 }
220#endif
221
222 // --------------------------------------------------------------------------
223
234 template <class Lhs_T, class Rhs_T>
235 [[nodiscard]] constexpr auto
236 eq (const Lhs_T& lhs, const Rhs_T& rhs)
237 {
238 return detail::eq_{ lhs, rhs };
239 }
240
251 template <class Lhs_T, class Rhs_T>
252 [[nodiscard]] constexpr auto
253 eq (Lhs_T* lhs, Rhs_T* rhs)
254 {
255 return detail::eq_{ lhs, rhs };
256 }
257
267 template <class Lhs_T, class Rhs_T>
268 [[nodiscard]] constexpr auto
269 ne (const Lhs_T& lhs, const Rhs_T& rhs)
270 {
271 return detail::ne_{ lhs, rhs };
272 }
273
283 template <class Lhs_T, class Rhs_T>
284 [[nodiscard]] constexpr auto
285 ne (Lhs_T* lhs, Rhs_T* rhs)
286 {
287 return detail::ne_{ lhs, rhs };
288 }
289
299 template <class Lhs_T, class Rhs_T>
300 [[nodiscard]] constexpr auto
301 gt (const Lhs_T& lhs, const Rhs_T& rhs)
302 {
303 return detail::gt_{ lhs, rhs };
304 }
305
315 template <class Lhs_T, class Rhs_T>
316 [[nodiscard]] constexpr auto
317 gt (Lhs_T* lhs, Rhs_T* rhs)
318 {
319 return detail::gt_{ lhs, rhs };
320 }
321
331 template <class Lhs_T, class Rhs_T>
332 [[nodiscard]] constexpr auto
333 ge (const Lhs_T& lhs, const Rhs_T& rhs)
334 {
335 return detail::ge_{ lhs, rhs };
336 }
337
347 template <class Lhs_T, class Rhs_T>
348 [[nodiscard]] constexpr auto
349 ge (Lhs_T* lhs, Rhs_T* rhs)
350 {
351 return detail::ge_{ lhs, rhs };
352 }
353
363 template <class Lhs_T, class Rhs_T>
364 [[nodiscard]] constexpr auto
365 lt (const Lhs_T& lhs, const Rhs_T& rhs)
366 {
367 return detail::lt_{ lhs, rhs };
368 }
369
379 template <class Lhs_T, class Rhs_T>
380 [[nodiscard]] constexpr auto
381 lt (Lhs_T* lhs, Rhs_T* rhs)
382 {
383 return detail::lt_{ lhs, rhs };
384 }
385
395 template <class Lhs_T, class Rhs_T>
396 [[nodiscard]] constexpr auto
397 le (const Lhs_T& lhs, const Rhs_T& rhs)
398 {
399 return detail::le_{ lhs, rhs };
400 }
401
411 template <class Lhs_T, class Rhs_T>
412 [[nodiscard]] constexpr auto
413 le (Lhs_T* lhs, Rhs_T* rhs)
414 {
415 return detail::le_{ lhs, rhs };
416 }
417
429 template <class Expr_T>
430 [[nodiscard]] constexpr auto
431 _not (const Expr_T& expr)
432 {
433 return detail::not_{ expr };
434 }
435
449 template <class Lhs_T, class Rhs_T>
450 [[nodiscard]] constexpr auto
451 _and (const Lhs_T& lhs, const Rhs_T& rhs)
452 {
453 return detail::and_{ lhs, rhs };
454 }
455
469 template <class Lhs_T, class Rhs_T>
470 [[nodiscard]] constexpr auto
471 _or (const Lhs_T& lhs, const Rhs_T& rhs)
472 {
473 return detail::or_{ lhs, rhs };
474 }
475
479 template <class T>
480 [[nodiscard]] constexpr auto
481 mut (const T& t) noexcept -> T&
482 {
483 return const_cast<T&> (t);
484 }
485
486 // --------------------------------------------------------------------------
487
499 namespace operators
500 {
505 [[nodiscard]] constexpr auto
506 operator== (std::string_view lhs, std::string_view rhs)
507 {
508 return detail::eq_{ lhs, rhs };
509 }
510
515 [[nodiscard]] constexpr auto
516 operator!= (std::string_view lhs, std::string_view rhs)
517 {
518 return detail::ne_{ lhs, rhs };
519 }
520
525 template <class T,
527 [[nodiscard]] constexpr auto
528 operator== (T&& lhs, T&& rhs)
529 {
530 return detail::eq_{ static_cast<T&&> (lhs), static_cast<T&&> (rhs) };
531 }
532
537 template <class T,
539 [[nodiscard]] constexpr auto
540 operator!= (T&& lhs, T&& rhs)
541 {
542 return detail::ne_{ static_cast<T&&> (lhs), static_cast<T&&> (rhs) };
543 }
544
550 template <class Lhs_T, class Rhs_T,
553 = 0>
554 [[nodiscard]] constexpr auto
555 operator== (const Lhs_T& lhs, const Rhs_T& rhs)
556 {
557 return detail::eq_{ lhs, rhs };
558 }
559
565 template <class Lhs_T, class Rhs_T,
568 = 0>
569 [[nodiscard]] constexpr auto
570 operator!= (const Lhs_T& lhs, const Rhs_T& rhs)
571 {
572 return detail::ne_{ lhs, rhs };
573 }
574
580 template <class Lhs_T, class Rhs_T,
583 = 0>
584 [[nodiscard]] constexpr auto
585 operator> (const Lhs_T& lhs, const Rhs_T& rhs)
586 {
587 return detail::gt_{ lhs, rhs };
588 }
589
595 template <class Lhs_T, class Rhs_T,
598 = 0>
599 [[nodiscard]] constexpr auto
600 operator>= (const Lhs_T& lhs, const Rhs_T& rhs)
601 {
602 return detail::ge_{ lhs, rhs };
603 }
604
610 template <class Lhs_T, class Rhs_T,
613 = 0>
614 [[nodiscard]] constexpr auto
615 operator< (const Lhs_T& lhs, const Rhs_T& rhs)
616 {
617 return detail::lt_{ lhs, rhs };
618 }
619
625 template <class Lhs_T, class Rhs_T,
628 = 0>
629 [[nodiscard]] constexpr auto
630 operator<= (const Lhs_T& lhs, const Rhs_T& rhs)
631 {
632 return detail::le_{ lhs, rhs };
633 }
634
640 template <class Lhs_T, class Rhs_T,
643 = 0>
644 [[nodiscard]] constexpr auto
645 operator and (const Lhs_T& lhs, const Rhs_T& rhs)
646 {
647 return detail::and_{ lhs, rhs };
648 }
649
655 template <class Lhs_T, class Rhs_T,
658 = 0>
659 [[nodiscard]] constexpr auto
660 operator or (const Lhs_T& lhs, const Rhs_T& rhs)
661 {
662 return detail::or_{ lhs, rhs };
663 }
664
670 template <class T, type_traits::requires_t<type_traits::is_op_v<T>> = 0>
671 [[nodiscard]] constexpr auto
672 operator not(const T& t)
673 {
674 return detail::not_{ t };
675 }
676 } // namespace operators
677
678 namespace utility
679 {
687 [[nodiscard]] bool
688 is_match (std::string_view input, std::string_view pattern);
689
699 template <class T, class Delim_T>
700 [[nodiscard]] auto
701 split (T input, Delim_T delim) -> std::vector<T>;
702
703 } // namespace utility
704
705 // --------------------------------------------------------------------------
706} // namespace micro_os_plus::micro_test_plus
707
708#if defined(__GNUC__)
709#pragma GCC diagnostic pop
710#endif
711
712// ----------------------------------------------------------------------------
713
714#endif // __cplusplus
715
716// ===== Inline & template implementations ====================================
717
719
720// All other inlines.
721#include "inlines.h"
722
723// ----------------------------------------------------------------------------
724
725#endif // MICRO_TEST_PLUS_MICRO_TEST_PLUS_H_
726
727// ----------------------------------------------------------------------------
Class template for a deferred reporter specific to an expression.
Definition detail.h:735
Local implementation of the std::source_location.
Definition reflection.h:57
static constexpr auto current(const char *file="unknown", unsigned int line={}) noexcept
Definition reflection.h:60
Reporter to display the test results. For failed tests it prints the actual values of the operands,...
The test runner. It maintains a list of test suites which automatically register themselves in their ...
Definition test-runner.h:51
Base class for all test suites.
Definition test-suite.h:50
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:92
auto split(T input, Delim_T delim) -> std::vector< T >
Split a string into a vector of sub-strings.
Definition inlines.h:174
bool is_match(std::string_view input, std::string_view pattern)
Check if a string matches a pattern.
Separate namespace with custom operators.
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:321
Less than or equal comparator.
Definition detail.h:438
Operator to check if the expression does not throw any exception.
Definition detail.h:665
Operator to check if the expression throws a specific exception.
Definition detail.h:599