Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/tests/SelfTest/UsageTests/MatchersConstexpr.tests.cpp
blob: 659ce869295e518cb3ff40004c5cb2f16ba9019b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

//              Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
//   (See accompanying file LICENSE.txt or copy at
//        https://www.boost.org/LICENSE_1_0.txt)

// SPDX-License-Identifier: BSL-1.0

#include <Progmasoft/Catch3/Internal/CompilerCapabilities.hpp>

#if defined( CATCH_INTERNAL_CONSTEXPR_MATCHERS_ENABLED )

#include <Progmasoft/Catch3/TestMacros.hpp>
#include <Progmasoft/Catch3/Matchers/Templated.hpp>
#include <Progmasoft/Catch3/Matchers/ContainerProperties.hpp>
#include <Progmasoft/Catch3/Matchers/Quantifiers.hpp>
#include <Progmasoft/Catch3/Matchers/Contains.hpp>
#include <Progmasoft/Catch3/Matchers/RangeEquals.hpp>

#include <array>

namespace {
    struct MatchAllMatcher final : public Catch::Matchers::MatcherGenericBase {
    public:
        template <typename Any>
        constexpr bool match( Any&& ) const {
            return true;
        }

        std::string describe() const override {
            using namespace std::string_literals;
            return "Matches anything"s;
        }
    };

    constexpr MatchAllMatcher MatchAll() { return MatchAllMatcher(); }

    struct MatchTrueMatcher final : public Catch::Matchers::MatcherGenericBase {
    public:
        constexpr bool match( bool b ) const {
            return b;
        }

        std::string describe() const override {
            using namespace std::string_literals;
            return "Matches true"s;
        }
    };

    constexpr MatchTrueMatcher MatchTrue() { return MatchTrueMatcher(); }

    constexpr std::array<bool, 3> compute_bools( int type ) {
        switch ( type ) {
        case 0:
            return { true, true, true };
        case 1:
            return { false, true, false };
        case 2:
            return { false, false, false };
        case 3:
            return { true, false, false };
        case 4:
            return { true, true, false };
        default:
            return { false, false, false };
        }
    }

} // namespace

TEST_CASE( "Constexpr support for matchers", "[constexpr][matchers][approvals]" ) {
    STATIC_REQUIRE( MatchAll().match( 1 ) );
    STATIC_REQUIRE_THAT( 1, MatchAll() );
}

TEST_CASE( "IsEmpty and HasSize matchers can be used in constexpr contexts",
           "[constexpr][matchers][approvals]" ){
    using namespace Catch::Matchers;
    static constexpr std::array<int, 0> empty{};
    STATIC_REQUIRE_THAT( empty, IsEmpty() );
    static constexpr int arr[1] = { 2 };
    STATIC_REQUIRE_THAT( arr, SizeIs( 1 ) );
    STATIC_REQUIRE_THAT( arr, SizeIs( MatchAll() ) );
}

TEST_CASE( "Quantifier matchers can be used in constexpr contexts",
           "[constexpr][matchers][approvals]" ) {
    using namespace Catch::Matchers;
    STATIC_REQUIRE_THAT( compute_bools( 0 ), AllTrue() );
    STATIC_REQUIRE_THAT( compute_bools( 1 ), AnyTrue() );
    STATIC_REQUIRE_THAT( compute_bools( 2 ), NoneTrue() );

    STATIC_REQUIRE_THAT( compute_bools( 0 ), AllMatch( MatchTrue() ) );
    STATIC_REQUIRE_THAT( compute_bools( 1 ), AnyMatch( MatchTrue() ) );
    STATIC_REQUIRE_THAT( compute_bools( 2 ), NoneMatch( MatchTrue() ) );
}

TEST_CASE( "Generic Equals matchers can be used in constexpr contexts",
           "[constexpr][matchers][approvals]" ) {
    using Catch::Matchers::Contains;
    STATIC_REQUIRE_THAT( compute_bools( 0 ), Contains( true ) );
    STATIC_REQUIRE_THAT( compute_bools( 1 ), Contains( MatchTrue() ) );
    STATIC_REQUIRE_THAT( compute_bools( 2 ), Contains( true, std::not_equal_to<>{} ) );
}

TEST_CASE( "Range equals matchers can be used in constexpr contexts",
           "[constexpr][matchers][approvals]" ) {
    using Catch::Matchers::RangeEquals;
    using Catch::Matchers::UnorderedRangeEquals;
    STATIC_REQUIRE_THAT( compute_bools( 0 ), RangeEquals( compute_bools( 0 ) ) );
    STATIC_REQUIRE_THAT( compute_bools( 2 ), RangeEquals( compute_bools( 0 ), std::not_equal_to<>{} ) );
    STATIC_REQUIRE_THAT( compute_bools( 1 ), UnorderedRangeEquals( compute_bools( 3 ) ) );
    STATIC_REQUIRE_THAT( compute_bools( 1 ), UnorderedRangeEquals( compute_bools( 4 ), std::not_equal_to<>{} ) );
}

// Combining matchers needs C++26 and P2738, so they are in separate preprocessor block
#    if __cpp_constexpr >= 202306L

TEST_CASE("Constexpr support for combining matchers",
    "[constexpr][matchers][approvals]") {
    STATIC_REQUIRE( ( MatchAll() && MatchAll() ).match( 1 ) );
    STATIC_REQUIRE( ( MatchAll() || MatchAll() ).match( 1 ) );
    STATIC_REQUIRE( ( !!MatchAll() ).match( 1 ) );
    STATIC_REQUIRE_THAT( 1, MatchAll() && MatchAll() );
    STATIC_REQUIRE_THAT( 1, MatchAll() || MatchAll() );
    STATIC_REQUIRE_THAT( 1, !!MatchAll() );
}

#endif // __cpp_constexpr >= 202306L

#endif