blob: 1567bd707fe6a1dd7ef074bc76124b4e7b03c197 [file]
/*
* Copyright (C) 2026 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RetainRef.h>
namespace TestWebKitAPI {
TEST(RetainRef, AdoptCFRef)
{
RetainRef<CFArrayRef> array = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
EXPECT_EQ(1, CFGetRetainCount(array.get()));
EXPECT_EQ(0, CFArrayGetCount(array.get()));
}
TEST(RetainRef, RetainRefFromValue)
{
RetainPtr<CFArrayRef> source = adoptCF(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
EXPECT_EQ(1, CFGetRetainCount(source.get()));
{
RetainRef<CFArrayRef> ref = retainRef(source.get());
EXPECT_EQ(2, CFGetRetainCount(source.get()));
EXPECT_EQ(source.get(), ref.get());
}
EXPECT_EQ(1, CFGetRetainCount(source.get()));
}
TEST(RetainRef, CopyConstructor)
{
RetainRef<CFArrayRef> a = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
EXPECT_EQ(1, CFGetRetainCount(a.get()));
{
RetainRef<CFArrayRef> b = a;
EXPECT_EQ(2, CFGetRetainCount(a.get()));
EXPECT_EQ(a.get(), b.get());
}
EXPECT_EQ(1, CFGetRetainCount(a.get()));
}
TEST(RetainRef, MoveConstructor)
{
RetainRef<CFArrayRef> a = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
CFArrayRef raw = a.get();
EXPECT_EQ(1, CFGetRetainCount(raw));
RetainRef<CFArrayRef> b = WTF::move(a);
EXPECT_EQ(1, CFGetRetainCount(raw));
EXPECT_EQ(raw, b.get());
}
TEST(RetainRef, FromRetainPtrReleaseNonNull)
{
RetainPtr<CFArrayRef> ptr = adoptCF(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
CFArrayRef raw = ptr.get();
EXPECT_EQ(1, CFGetRetainCount(raw));
RetainRef<CFArrayRef> ref = ptr.releaseNonNull();
EXPECT_EQ(1, CFGetRetainCount(raw));
EXPECT_EQ(raw, ref.get());
EXPECT_EQ(nullptr, ptr.get());
}
TEST(RetainRef, MoveToRetainPtr)
{
RetainRef<CFArrayRef> ref = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
CFArrayRef raw = ref.get();
EXPECT_EQ(1, CFGetRetainCount(raw));
{
RetainPtr<CFArrayRef> ptr { WTF::move(ref) };
EXPECT_EQ(1, CFGetRetainCount(raw));
EXPECT_EQ(raw, ptr.get());
}
}
TEST(RetainRef, AssignToRetainPtr)
{
RetainPtr<CFArrayRef> ptr = adoptCF(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
CFArrayRef rawOriginal = ptr.get();
EXPECT_EQ(1, CFGetRetainCount(rawOriginal));
RetainRef<CFArrayRef> ref = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
CFArrayRef rawNew = ref.get();
EXPECT_EQ(1, CFGetRetainCount(rawNew));
ptr = WTF::move(ref);
EXPECT_EQ(rawNew, ptr.get());
EXPECT_EQ(1, CFGetRetainCount(rawNew));
}
TEST(RetainRef, CtadFromRetainRef)
{
RetainRef<CFArrayRef> ref = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
CFArrayRef raw = ref.get();
EXPECT_EQ(1, CFGetRetainCount(raw));
RetainPtr ptr { WTF::move(ref) };
static_assert(std::is_same_v<decltype(ptr), RetainPtr<CFArrayRef>>);
EXPECT_EQ(raw, ptr.get());
EXPECT_EQ(1, CFGetRetainCount(raw));
}
TEST(RetainRef, ExplicitFromRetainPtr)
{
RetainPtr<CFArrayRef> ptr = adoptCF(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
EXPECT_EQ(1, CFGetRetainCount(ptr.get()));
{
RetainRef<CFArrayRef> ref { ptr.get() };
EXPECT_EQ(2, CFGetRetainCount(ptr.get()));
EXPECT_EQ(ptr.get(), ref.get());
}
EXPECT_EQ(1, CFGetRetainCount(ptr.get()));
}
TEST(RetainRef, Assignment)
{
RetainRef<CFArrayRef> a = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
RetainRef<CFArrayRef> b = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
CFArrayRef rawB = b.get();
a = b;
EXPECT_EQ(rawB, a.get());
EXPECT_EQ(2, CFGetRetainCount(rawB));
}
TEST(RetainRef, HashMap)
{
HashMap<RetainRef<CFArrayRef>, int> map;
RetainRef<CFArrayRef> key = adoptCFRef(CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr));
map.add(key, 42);
EXPECT_EQ(1u, map.size());
EXPECT_EQ(42, map.get(key));
}
} // namespace TestWebKitAPI