blob: b33c0f608a703d0ea617d72c40baa8ba74952ad4 [file] [log] [blame]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <zircon/assert.h>
#include <zxtest/zxtest.h>
extern "C" uint32_t EchoValue(uint32_t val);
namespace {
// Asserts whose predicate evaluates to `true` should not terminate the process.
// In the case of debug asserts, we should always pass; either debug asserts are
// enabled and the predicate is true, or asserts are disabled and the statement
// should disappear.
TEST(ZxAssertCppTest, ZxAssertValidPredicatePasses) {
constexpr uint32_t kExpected = __LINE__;
ZX_ASSERT(EchoValue(kExpected) == kExpected);
}
TEST(ZxAssertCppTest, ZxAssertMsgValidPredicatePasses) {
constexpr uint32_t kExpected = __LINE__;
// Note; this ASSERT test (and the related forms below) serve double duty. In
// addition to checking their related assert, they also make sure that the
// assert implementation supports the new C++17 `if` syntax which allows
// variables and their initialization to be introduced into the limited scoped
// of the `if/else` statement.
ZX_ASSERT_MSG(const uint32_t val = EchoValue(kExpected);
val == kExpected, "Expected %u, Got %u; ", kExpected, val);
}
TEST(ZxAssertCppTest, ZxDebugAssertValidPredicatePasses) {
constexpr uint32_t kExpected = __LINE__;
ZX_DEBUG_ASSERT(EchoValue(kExpected) == kExpected);
}
TEST(ZxAssertCppTest, ZxDebugAssertMsgValidPredicatePasses) {
constexpr uint32_t kExpected = __LINE__;
ZX_DEBUG_ASSERT_MSG(const uint32_t val = EchoValue(kExpected);
val == kExpected, "Expected %u, Got %u; ", kExpected, val);
}
// Asserts whose predicate evaluates to `false` should fail and terminate the
// program (we expect program death). Test this using the test framework's
// ASSERT_DEATH macro. In the case of debug asserts, we expect to program to die
// iff debug asserts are enabled, otherwise we should be able to make the same
// assert (with a false predicate) and still have the program survive.
TEST(ZxAssertCppTest, ZxAssertInvalidPredicateFails) {
constexpr uint32_t kExpected = __LINE__;
constexpr uint32_t kActual = kExpected + 1;
ASSERT_DEATH([]() { ZX_ASSERT(EchoValue(kActual) == kExpected); });
}
TEST(ZxAssertCppTest, ZxAssertMsgInvalidPredicateFails) {
constexpr uint32_t kExpected = __LINE__;
constexpr uint32_t kActual = kExpected + 1;
ASSERT_DEATH([]() {
ZX_ASSERT_MSG(const uint32_t val = EchoValue(kActual);
val == kExpected, "Expected %u, Got %u; ", kExpected, val);
});
}
TEST(ZxAssertCppTest, ZxDebugAssertInvalidPredicateFails) {
constexpr uint32_t kExpected = __LINE__;
constexpr uint32_t kActual = kExpected + 1;
#if ZX_DEBUG_ASSERT_IMPLEMENTED
ASSERT_DEATH([]() { ZX_DEBUG_ASSERT(EchoValue(kActual) == kExpected); });
#else
ZX_DEBUG_ASSERT(EchoValue(kActual) == kExpected);
#endif
}
TEST(ZxAssertCppTest, ZxDebugAssertMsgInvalidPredicateFails) {
constexpr uint32_t kExpected = __LINE__;
constexpr uint32_t kActual = kExpected + 1;
#if ZX_DEBUG_ASSERT_IMPLEMENTED
ASSERT_DEATH([]() {
ZX_DEBUG_ASSERT_MSG(const uint32_t val = EchoValue(kActual);
val == kExpected, "Expected %u, Got %u; ", kExpected, val);
});
#else
ZX_DEBUG_ASSERT_MSG(const uint32_t val = EchoValue(kActual);
val == kExpected, "Expected %u, Got %u; ", kExpected, val);
#endif
}
// There is really no good way to write negative compile-time tests, but we can
// (at least) have a few tests which can be manually enabled and run by someone
// at the time they modify assert.h
[[maybe_unused]] void NegativeCompilationChecks() {
[[maybe_unused]] uint32_t val{0};
// Assignment without extra ()s during a ZX_ASSERT should fail to compile.
#if TEST_WILL_NOT_COMPILE || 0
ZX_ASSERT(val = 5);
#endif
// Assignment without extra ()s during a ZX_ASSERT_MSG should fail to compile.
#if TEST_WILL_NOT_COMPILE || 0
ZX_ASSERT_MSG(val = 5, "Should not compile");
#endif
// Assignment without extra ()s during a ZX_DEBUG_ASSERT should fail to compile.
#if TEST_WILL_NOT_COMPILE || 0
ZX_DEBUG_ASSERT(val = 5);
#endif
// Assignment without extra ()s during a ZX_DEBUG_ASSERT_MSG should fail to compile.
#if TEST_WILL_NOT_COMPILE || 0
ZX_DEBUG_ASSERT_MSG(val = 5, "Should not compile");
#endif
}
} // namespace