Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/core/azure-core/test/ut/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ endif()

add_executable (
azure-core-test
test_traits.hpp
authorization_challenge_parser_test.cpp
azure_core_test.cpp
base64_test.cpp
Expand Down
50 changes: 49 additions & 1 deletion sdk/core/azure-core/test/ut/etag_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT

#include "test_traits.hpp"
#include <gtest/gtest.h>

#include <azure/core/etag.hpp>
Expand Down Expand Up @@ -259,6 +259,54 @@ TEST(ETag, EqualsWeak)
EXPECT_FALSE(ETag::Equals(weakTagtwo, weakTagTwo, ETag::ETagComparison::Weak));
}

TEST(Etag, Assignable)
{
EXPECT_TRUE(ClassTraits<ETag>::is_assignable<ETag>());
EXPECT_TRUE(ClassTraits<ETag>::is_assignable<const ETag>());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_assignable<ETag>());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_assignable<const ETag>());
EXPECT_TRUE(ClassTraits<ETag>::is_nothrow_assignable<ETag>());
EXPECT_FALSE(ClassTraits<ETag>::is_nothrow_assignable<const ETag>());
}

TEST(Etag, Constructible)
{
EXPECT_TRUE((ClassTraits<ETag, const std::string&>::is_constructible()));
EXPECT_FALSE((ClassTraits<ETag, const std::string&>::is_trivially_constructible()));
EXPECT_FALSE((ClassTraits<ETag, const std::string&>::is_nothrow_constructible()));
EXPECT_TRUE(ClassTraits<ETag>::is_default_constructible());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_default_constructible());
EXPECT_FALSE(ClassTraits<ETag>::is_nothrow_default_constructible());
}

TEST(Etag, CopyAndMoveConstructible)
{
EXPECT_TRUE(ClassTraits<ETag>::is_copy_constructible());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_copy_constructible());
EXPECT_FALSE(ClassTraits<ETag>::is_nothrow_copy_constructible());
EXPECT_TRUE(ClassTraits<ETag>::is_move_constructible());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_move_constructible());
EXPECT_TRUE(ClassTraits<ETag>::is_nothrow_move_constructible());
}

TEST(Etag, CopyAndMoveAssignable)
{
EXPECT_TRUE(ClassTraits<ETag>::is_copy_assignable());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_copy_assignable());
EXPECT_FALSE(ClassTraits<ETag>::is_nothrow_copy_assignable());
EXPECT_TRUE(ClassTraits<ETag>::is_move_assignable());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_move_assignable());
EXPECT_TRUE(ClassTraits<ETag>::is_nothrow_move_assignable());
}

TEST(Etag, Destructible)
{
EXPECT_TRUE(ClassTraits<ETag>::is_destructible());
EXPECT_FALSE(ClassTraits<ETag>::is_trivially_destructible());
EXPECT_TRUE(ClassTraits<ETag>::is_nothrow_destructible());
EXPECT_FALSE(ClassTraits<ETag>::has_virtual_destructor());
}

#if GTEST_HAS_DEATH_TEST
TEST(ETag, PreCondition)
{
Expand Down
132 changes: 132 additions & 0 deletions sdk/core/azure-core/test/ut/test_traits.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include <type_traits>

template <typename T, typename... Args> struct ClassTraits
{
static_assert(std::is_class<T>::value, "ClassTraits can only be used with class types");

// Check if T is constructible from Args
static constexpr bool is_constructible() { return std::is_constructible<T, Args...>::value; }

// Check if T is trivially constructible from Args
static constexpr bool is_trivially_constructible()
{
return std::is_trivially_constructible<T, Args...>::value;
}

// Check if T is nothrow constructible from Args
static constexpr bool is_nothrow_constructible()
{
return std::is_nothrow_constructible<T, Args...>::value;
}

// Check if T has a default constructor
static constexpr bool is_default_constructible()
{
return std::is_default_constructible<T>::value;
}

// Check if T has a trivially default constructor
static constexpr bool is_trivially_default_constructible()
{
return std::is_trivially_default_constructible<T>::value;
}

// Check if T has a nothrow default constructor
static constexpr bool is_nothrow_default_constructible()
{
return std::is_nothrow_default_constructible<T>::value;
}

// Check if T is copy-constructible
static constexpr bool is_copy_constructible() { return std::is_copy_constructible<T>::value; }

// Check if T is trivially copy-constructible
static constexpr bool is_trivially_copy_constructible()
{
return std::is_trivially_copy_constructible<T>::value;
}

// Check if T is nothrow copy-constructible
static constexpr bool is_nothrow_copy_constructible()
{
return std::is_nothrow_copy_constructible<T>::value;
}

// Check if T is move-constructible
static constexpr bool is_move_constructible() { return std::is_move_constructible<T>::value; }

// Check if T is trivially move-constructible
static constexpr bool is_trivially_move_constructible()
{
return std::is_trivially_move_constructible<T>::value;
}

// Check if T is nothrow move-constructible
static constexpr bool is_nothrow_move_constructible()
{
return std::is_nothrow_move_constructible<T>::value;
}

// Check if T is assignable from U
template <typename U> static constexpr bool is_assignable()
{
return std::is_assignable<T&, U>::value;
}

// Check if T is trivially assignable from U
template <typename U> static constexpr bool is_trivially_assignable()
{
return std::is_trivially_assignable<T&, U>::value;
}

// Check if T is nothrow assignable from U
template <typename U> static constexpr bool is_nothrow_assignable()
{
return std::is_nothrow_assignable<T&, U>::value;
}

// Check if T is copy-assignable
static constexpr bool is_copy_assignable() { return std::is_copy_assignable<T>::value; }

// Check if T is trivially copy-assignable
static constexpr bool is_trivially_copy_assignable()
{
return std::is_trivially_copy_assignable<T>::value;
}

// Check if T is nothrow copy-assignable
static constexpr bool is_nothrow_copy_assignable()
{
return std::is_nothrow_copy_assignable<T>::value;
}

// Check if T is move-assignable
static constexpr bool is_move_assignable() { return std::is_move_assignable<T>::value; }

// Check if T is trivially move-assignable
static constexpr bool is_trivially_move_assignable()
{
return std::is_trivially_move_assignable<T>::value;
}

// Check if T is nothrow move-assignable
static constexpr bool is_nothrow_move_assignable()
{
return std::is_nothrow_move_assignable<T>::value;
}

// Check if T is destructible
static constexpr bool is_destructible() { return std::is_destructible<T>::value; }

// Check if T is trivially destructible
static constexpr bool is_trivially_destructible()
{
return std::is_trivially_destructible<T>::value;
}

// Check if T is nothrow destructible
static constexpr bool is_nothrow_destructible() { return std::is_nothrow_destructible<T>::value; }

// Check if T has virtual destructor
static constexpr bool has_virtual_destructor() { return std::has_virtual_destructor<T>::value; }
};