v8/test/unittests/heap/cppgc/finalizer-trait-unittest.cc
Michael Lippautz f701df1f3c cppgc: Rename unittest files
Adjust suffix to "-unittest" like everywhere else in V8.

Accept clang-format suggested changes.

Bug: chromium:1056170
Change-Id: I54c1396e79aff87c052233853d7fe560337eeecf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2190410
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Auto-Submit: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67672}
2020-05-08 08:50:48 +00:00

121 lines
3.3 KiB
C++

// Copyright 2020 the V8 project 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 "include/cppgc/internal/finalizer-trait.h"
#include <type_traits>
#include "testing/gtest/include/gtest/gtest.h"
namespace cppgc {
namespace internal {
namespace {
// Trivially destructible types.
class TypeWithoutDestructor final {};
class TypeWithPrimitive final {
public:
int foo = 0;
};
class InvokeCounter {
public:
static size_t kCallcount;
static void Reset() { kCallcount = 0; }
static void Invoke() { kCallcount++; }
};
size_t InvokeCounter::kCallcount = 0;
// Regular C++ use cases.
class TypeWithDestructor final : public InvokeCounter {
public:
~TypeWithDestructor() { Invoke(); }
};
class TypeWithVirtualDestructorBase {
public:
virtual ~TypeWithVirtualDestructorBase() = default;
};
class TypeWithVirtualDestructorChild final
: public TypeWithVirtualDestructorBase,
public InvokeCounter {
public:
~TypeWithVirtualDestructorChild() final { Invoke(); }
};
// Manual dispatch to avoid vtables.
class TypeWithCustomFinalizationMethod final : public InvokeCounter {
public:
void FinalizeGarbageCollectedObject() { Invoke(); }
};
class TypeWithCustomFinalizationMethodAtBase {
public:
void FinalizeGarbageCollectedObject();
};
class TypeWithCustomFinalizationMethodAtBaseChild
: public TypeWithCustomFinalizationMethodAtBase,
public InvokeCounter {
public:
~TypeWithCustomFinalizationMethodAtBaseChild() { Invoke(); }
};
void TypeWithCustomFinalizationMethodAtBase::FinalizeGarbageCollectedObject() {
// The test knows that base is only inherited by a single child. In practice
// users can maintain a map of valid types in already existing storage.
static_cast<TypeWithCustomFinalizationMethodAtBaseChild*>(this)
->~TypeWithCustomFinalizationMethodAtBaseChild();
}
template <typename Type>
void ExpectFinalizerIsInvoked(Type* object) {
InvokeCounter::Reset();
EXPECT_NE(nullptr, FinalizerTrait<Type>::kCallback);
FinalizerTrait<Type>::kCallback(object);
EXPECT_EQ(1u, InvokeCounter::kCallcount);
operator delete(object);
}
} // namespace
TEST(FinalizerTrait, TypeWithoutDestructorHasNoFinalizer) {
static_assert(std::is_trivially_destructible<TypeWithoutDestructor>::value,
"trivially destructible");
EXPECT_EQ(nullptr, FinalizerTrait<TypeWithoutDestructor>::kCallback);
}
TEST(FinalizerTrait, TypeWithPrimitiveHasNoFinalizer) {
static_assert(std::is_trivially_destructible<TypeWithPrimitive>::value,
"trivially destructible");
EXPECT_EQ(nullptr, FinalizerTrait<TypeWithPrimitive>::kCallback);
}
TEST(FinalizerTrait, FinalizerForTypeWithDestructor) {
ExpectFinalizerIsInvoked(new TypeWithDestructor());
}
TEST(FinalizerTrait, FinalizerForTypeWithVirtualBaseDtor) {
TypeWithVirtualDestructorBase* base = new TypeWithVirtualDestructorChild();
ExpectFinalizerIsInvoked(base);
}
TEST(FinalizerTrait, FinalizerForCustomFinalizationMethod) {
ExpectFinalizerIsInvoked(new TypeWithCustomFinalizationMethod());
}
TEST(FinalizerTrait, FinalizerForCustomFinalizationMethodInBase) {
TypeWithCustomFinalizationMethodAtBase* base =
new TypeWithCustomFinalizationMethodAtBaseChild();
ExpectFinalizerIsInvoked(base);
}
} // namespace internal
} // namespace cppgc