avs-device-sdk/shared/acsdkManufactory/test/ManufactoryUtilsTest.cpp

328 lines
14 KiB
C++

/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
/// @file ManufactoryUtilsTest.cpp
/**
* Test of acsdkManufactory's compile time utilities.
*/
#include <iostream>
#include <memory>
#include <tuple>
#include <gtest/gtest.h>
#include "acsdkManufactory/Import.h"
#include "acsdkManufactory/OptionalImport.h"
#include "acsdkManufactory/internal/Utils.h"
namespace alexaClientSDK {
namespace acsdkManufactory {
namespace internal {
/**
* Template used to create distinct classes with which to test compile time utilities.
*
* @tparam x An integer used to distinguish between instantiations of this template.
*/
template <int x>
class Foo {
public:
};
/**
* Function used to invoke compile time utilities.
*/
TEST(ManufactoryUtilsTest, manufactoryUtilsFunctions) {
// Test ContainsType
static_assert(!ContainsType<std::tuple<>, Foo<1>>::value, "test");
static_assert(ContainsType<std::tuple<Foo<1>>, Foo<1>>::value, "test");
static_assert(!ContainsType<std::tuple<Foo<2>>, Foo<1>>::value, "test");
static_assert(ContainsType<std::tuple<Foo<1>, Foo<2>>, Foo<1>>::value, "test");
static_assert(!ContainsType<std::tuple<Foo<1>, Foo<2>>, Foo<3>>::value, "test");
static_assert(ContainsType<std::tuple<Foo<1>, Foo<1>>, Foo<1>>::value, "test");
static_assert(!ContainsType<std::tuple<Foo<2>, Foo<2>>, Foo<1>>::value, "test");
static_assert(ContainsType<std::tuple<Foo<1>, Foo<2>, Foo<3>>, Foo<3>>::value, "test");
static_assert(!ContainsType<std::tuple<Foo<1>, Foo<2>, Foo<3>>, Foo<4>>::value, "test");
// Test ContainsTypes
static_assert(!ContainsTypes<std::tuple<>, Foo<1>>::value, "test");
static_assert(ContainsTypes<std::tuple<Foo<1>>, Foo<1>>::value, "test");
static_assert(!ContainsTypes<std::tuple<Foo<1>>, Foo<2>>::value, "test");
static_assert(!ContainsTypes<std::tuple<Foo<1>>, Foo<1>, Foo<2>>::value, "test");
static_assert(ContainsTypes<std::tuple<Foo<1>, Foo<2>>, Foo<1>>::value, "test");
static_assert(ContainsTypes<std::tuple<Foo<1>, Foo<2>>, Foo<1>, Foo<1>>::value, "test");
static_assert(ContainsTypes<std::tuple<Foo<1>, Foo<2>>, Foo<2>, Foo<2>>::value, "test");
static_assert(ContainsTypes<std::tuple<Foo<1>, Foo<2>>, Foo<1>, Foo<2>>::value, "test");
static_assert(ContainsTypes<std::tuple<Foo<1>, Foo<1>>, Foo<1>>::value, "test");
static_assert(!ContainsTypes<std::tuple<Foo<1>, Foo<1>>, Foo<2>>::value, "test");
static_assert(ContainsTypes<std::tuple<Foo<1>, Foo<2>, Foo<3>>, Foo<1>>::value, "test");
static_assert(!ContainsTypes<std::tuple<Foo<1>, Foo<2>, Foo<3>>, Foo<4>>::value, "test");
// Test ContainsTupleTypes
static_assert(ContainsTupleTypes<std::tuple<>, std::tuple<>>::value, "test");
static_assert(!ContainsTupleTypes<std::tuple<>, std::tuple<Foo<1>>>::value, "test");
static_assert(ContainsTupleTypes<std::tuple<Foo<1>, Foo<1>>, std::tuple<>>::value, "test");
static_assert(ContainsTupleTypes<std::tuple<Foo<1>, Foo<1>>, std::tuple<Foo<1>>>::value, "test");
static_assert(!ContainsTupleTypes<std::tuple<Foo<1>, Foo<1>>, std::tuple<Foo<2>>>::value, "test");
static_assert(ContainsTupleTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<>>::value, "test");
static_assert(ContainsTupleTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<Foo<1>>>::value, "test");
static_assert(ContainsTupleTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<Foo<2>>>::value, "test");
static_assert(ContainsTupleTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<Foo<1>, Foo<2>>>::value, "test");
static_assert(!ContainsTupleTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<Foo<2>, Foo<3>>>::value, "test");
static_assert(!ContainsTupleTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<Foo<3>, Foo<2>>>::value, "test");
// Test HasRequiredImport
static_assert(!HasRequiredImport<>::value, "test");
static_assert(!HasRequiredImport<Foo<1>>::value, "test");
static_assert(HasRequiredImport<Import<Foo<1>>>::value, "test");
static_assert(!HasRequiredImport<Foo<1>, Foo<2>>::value, "test");
static_assert(HasRequiredImport<Import<Foo<1>>, Foo<2>>::value, "test");
static_assert(HasRequiredImport<Import<Foo<1>>, Import<Foo<2>>>::value, "test");
static_assert(HasRequiredImport<Foo<1>, Import<Foo<2>>>::value, "test");
static_assert(!HasRequiredImport<Foo<1>, Foo<2>, Foo<3>>::value, "test");
static_assert(HasRequiredImport<Import<Foo<1>>, Foo<2>, Foo<3>>::value, "test");
static_assert(HasRequiredImport<Import<Foo<1>>, Import<Foo<2>, Foo<3>>>::value, "test");
static_assert(HasRequiredImport<Foo<1>, Import<Foo<2>>, Foo<3>>::value, "test");
static_assert(!HasRequiredImport<Foo<1>, Foo<1>>::value, "test");
static_assert(HasRequiredImport<Import<Foo<1>>, Import<Foo<1>>>::value, "test");
static_assert(!HasRequiredImport<OptionalImport<Foo<1>>, Foo<1>>::value, "test");
static_assert(!HasRequiredImport<OptionalImport<Foo<1>, Foo<1>>>::value, "test");
static_assert(HasRequiredImport<OptionalImport<Foo<1>>, Import<Foo<1>>>::value, "test");
// Test IsRequiredImport
static_assert(!IsRequiredImport<Foo<1>>::value, "test");
static_assert(IsRequiredImport<Import<Foo<1>>>::value, "test");
static_assert(!IsRequiredImport<OptionalImport<Foo<1>>>::value, "test");
// Test DedupTypes
DedupTypes<>::type x1 = {};
DedupTypes<Foo<1>>::type x2((Foo<1>()));
DedupTypes<Foo<1>, Foo<1>>::type x3((Foo<1>()));
DedupTypes<Foo<1>, Foo<2>>::type x4((Foo<1>()), (Foo<2>()));
DedupTypes<Foo<1>, Foo<2>, Foo<2>>::type x5((Foo<1>()), (Foo<2>()));
DedupTypes<Foo<1>, Foo<2>, Foo<1>, Foo<2>>::type x6((Foo<1>()), (Foo<2>()));
DedupTypes<Foo<1>, Foo<2>, Foo<2>, Foo<1>>::type x7((Foo<1>()), (Foo<2>()));
DedupTypes<Foo<1>, Foo<2>, Foo<3>, Foo<2>, Foo<1>>::type x8((Foo<1>()), (Foo<2>()), (Foo<3>()));
DedupTypes<Foo<1>, Foo<2>, Foo<3>, Foo<2>, Foo<3>, Foo<1>>::type x9((Foo<1>()), (Foo<2>()), (Foo<3>()));
DedupTypes<Foo<1>, Foo<2>, Foo<3>, Foo<2>, Foo<2>, Foo<2>>::type x10((Foo<1>()), (Foo<2>()), (Foo<3>()));
// Avoid annoying "unused variable" warnings.
std::cout << &x1 << &x2 << &x3 << &x4 << &x5 << &x6 << &x7 << &x8 << &x9 << &x10;
// Test RemoveTypes
RemoveTypes<std::tuple<>, std::tuple<>>::type x11 = {};
RemoveTypes<std::tuple<Foo<1>>, std::tuple<>>::type x12((Foo<1>()));
RemoveTypes<std::tuple<Foo<1>>, std::tuple<Foo<1>>>::type x13 = {};
RemoveTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<>>::type x14((Foo<1>()), (Foo<2>()));
RemoveTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<Foo<1>>>::type x15((Foo<2>()));
RemoveTypes<std::tuple<Foo<1>, Foo<2>>, std::tuple<Foo<2>>>::type x16((Foo<1>()));
RemoveTypes<std::tuple<Foo<1>, Foo<1>>, std::tuple<Foo<1>>>::type x17 = {};
RemoveTypes<std::tuple<Foo<1>, Foo<1>>, std::tuple<Foo<1>, Foo<1>>>::type x18 = {};
RemoveTypes<std::tuple<Foo<1>, Foo<1>>, std::tuple<Foo<2>>>::type x19((Foo<1>()), (Foo<1>()));
RemoveTypes<std::tuple<Foo<1>, Foo<2>, Foo<3>>, std::tuple<Foo<4>, Foo<3>, Foo<2>>>::type x20((Foo<1>()));
// Avoid annoying "unused variable" warnings.
std::cout << &x11 << &x12 << &x13 << &x14 << &x15 << &x16 << &x17 << &x18 << &x19 << &x20;
// Test GetImportsAndExports
GetImportsAndExports<>::type::exports x21 = {};
GetImportsAndExports<>::type::required x22 = {};
GetImportsAndExports<Foo<1>>::type::exports x23((Foo<1>()));
GetImportsAndExports<Foo<1>>::type::required x24 = {};
GetImportsAndExports<Foo<1>, Foo<1>>::type::exports x25((Foo<1>()));
GetImportsAndExports<Foo<1>, Foo<1>>::type::required x26 = {};
GetImportsAndExports<Foo<1>, Foo<2>>::type::exports x27((Foo<1>()), (Foo<2>()));
GetImportsAndExports<Foo<1>, Foo<2>>::type::required x28 = {};
GetImportsAndExports<Foo<1>, Foo<2>, Foo<3>>::type::exports x29((Foo<1>()), (Foo<2>()), (Foo<3>()));
GetImportsAndExports<Foo<1>, Foo<2>, Foo<3>>::type::required x30 = {};
GetImportsAndExports<Import<Foo<1>>, Foo<2>, Foo<3>>::type::exports x31((Foo<2>()), (Foo<3>()));
GetImportsAndExports<Import<Foo<1>>, Foo<2>, Foo<3>>::type::required x32((Foo<1>()));
GetImportsAndExports<Import<Foo<1>>, Import<Foo<2>>, Foo<3>>::type::exports x33((Foo<3>()));
GetImportsAndExports<Import<Foo<1>>, Import<Foo<2>>, Foo<3>>::type::required x34((Foo<1>()), (Foo<2>()));
GetImportsAndExports<Import<Foo<1>>, Import<Foo<2>>, Import<Foo<3>>>::type::exports x35 = {};
GetImportsAndExports<Import<Foo<1>>, Import<Foo<2>>, Import<Foo<3>>>::type::required x36(
(Foo<1>()), (Foo<2>()), (Foo<3>()));
GetImportsAndExports<Foo<1>, Import<Foo<2>>, Import<Foo<3>>>::type::exports x37((Foo<1>()));
GetImportsAndExports<Foo<1>, Import<Foo<2>>, Import<Foo<3>>>::type::required x38((Foo<2>()), (Foo<3>()));
// Avoid annoying "unused variable" warnings.
std::cout << &x21 << &x22 << &x23 << &x24 << &x25 << &x26 << &x27 << &x28 << &x29 << &x30;
std::cout << &x31 << &x32 << &x33 << &x34 << &x35 << &x36 << &x37 << &x38;
// Test Required x Optional Import / Exports
static_assert(std::tuple_size<GetImportsAndExports<>::type::optional>() == 0, "test");
static_assert(std::tuple_size<GetImportsAndExports<Foo<1>>::type::optional>() == 0, "test");
static_assert(std::tuple_size<GetImportsAndExports<Foo<1>, Foo<1>>::type::optional>() == 0, "test");
static_assert(std::tuple_size<GetImportsAndExports<Foo<1>, Foo<2>>::type::optional>() == 0, "test");
static_assert(std::tuple_size<GetImportsAndExports<Foo<1>, Foo<2>, Foo<3>>::type::optional>() == 0, "test");
static_assert(std::tuple_size<GetImportsAndExports<Import<Foo<1>>, Foo<2>, Foo<3>>::type::optional>() == 0, "test");
// Test static_assert(std::tuple_size<GetImportsAndExports with OptionalImport
static_assert(ContainsType<GetImportsAndExports<OptionalImport<Foo<1>>>::type::optional, Foo<1>>::value, "test");
static_assert(!ContainsType<GetImportsAndExports<OptionalImport<Foo<1>>>::type::required, Foo<1>>::value, "test");
// With export
static_assert(
!ContainsType<GetImportsAndExports<Foo<1>, OptionalImport<Foo<1>>>::type::optional, Foo<1>>::value, "test");
static_assert(
!ContainsType<GetImportsAndExports<Foo<1>, Import<Foo<1>>, OptionalImport<Foo<1>>>::type::optional, Foo<1>>::
value,
"test");
// Different combinations of Import and OptionalImport.
static_assert(
!ContainsType<GetImportsAndExports<Import<Foo<1>>, OptionalImport<Foo<1>>>::type::optional, Foo<1>>::value,
"test");
static_assert(
ContainsType<GetImportsAndExports<Import<Foo<1>>, OptionalImport<Foo<1>>>::type::required, Foo<1>>::value,
"test");
static_assert(
!ContainsType<GetImportsAndExports<Import<Foo<1>>, OptionalImport<Foo<2>>>::type::optional, Foo<1>>::value,
"test");
static_assert(
ContainsType<GetImportsAndExports<Import<Foo<1>>, OptionalImport<Foo<2>>>::type::optional, Foo<2>>::value,
"test");
static_assert(
ContainsType<GetImportsAndExports<Import<Foo<1>>, OptionalImport<Foo<2>>>::type::required, Foo<1>>::value,
"test");
static_assert(
!ContainsType<GetImportsAndExports<Import<Foo<1>>, OptionalImport<Foo<2>>>::type::required, Foo<2>>::value,
"test");
// Test make optional import.
static_assert(
ContainsType<GetImportsAndExports<Import<Foo<1>>, MakeOptional<Foo<1>>>::type::optional, Foo<1>>::value,
"test");
static_assert(
!ContainsType<GetImportsAndExports<Import<Foo<1>>, MakeOptional<Foo<1>>>::type::required, Foo<1>>::value,
"test");
// Test that large numbers of template parameters don't trigger degenerate compiler behavior.
GetImportsAndExports<
Import<Foo<1>>,
Foo<2>,
std::shared_ptr<Foo<3>>,
std::shared_ptr<Foo<4>>,
Import<Foo<5>>,
Import<Foo<6>>,
Import<Foo<7>>,
Foo<8>,
Import<std::shared_ptr<Foo<9>>>,
Foo<10>,
Import<Foo<11>>,
Foo<12>,
Import<Foo<13>>,
Import<Foo<14>>,
Foo<15>,
Foo<16>,
Foo<17>,
Import<Foo<18>>,
Import<Foo<19>>,
Import<Foo<20>>,
Foo<21>,
Import<Foo<22>>,
Foo<23>,
Import<Foo<24>>,
Import<Foo<25>>,
Import<std::shared_ptr<Foo<26>>>,
Foo<27>,
Foo<28>,
Import<std::shared_ptr<Foo<29>>>,
OptionalImport<std::shared_ptr<Foo<30>>>,
OptionalImport<Foo<31>>,
Import<Foo<32>>,
Import<Foo<33>>,
Foo<34>,
std::shared_ptr<Foo<35>>,
MakeOptional<std::shared_ptr<Foo<36>>>,
Import<std::shared_ptr<Foo<36>>>,
Foo<37>,
std::shared_ptr<Foo<38>>,
std::shared_ptr<Foo<39>>,
std::shared_ptr<Foo<40>>,
Foo<41>,
Foo<42>,
Foo<43>,
Foo<44>,
Foo<45>,
Foo<46>,
Foo<47>,
Foo<48>,
Foo<49>,
Foo<50>,
Foo<51>,
Foo<52>,
Foo<53>,
Foo<54>,
Foo<55>,
Foo<56>,
Foo<57>,
Foo<58>,
Foo<59>,
Foo<60>,
Foo<61>,
Foo<62>,
Foo<63>,
Foo<64>,
Foo<65>,
Foo<66>,
Foo<67>,
Foo<68>,
Foo<69>,
Foo<70>,
Foo<71>,
Foo<72>,
Foo<73>,
Foo<74>,
Foo<75>,
Foo<76>,
Foo<77>,
Foo<78>,
Foo<79>,
Foo<80>,
Foo<81>,
Foo<82>,
Foo<83>,
Foo<84>,
Foo<85>,
Foo<86>,
Foo<87>,
Foo<88>,
Foo<89>,
Foo<90>,
Foo<91>,
Foo<92>,
Foo<93>,
Foo<94>,
Foo<85>,
Foo<96>,
Foo<97>,
Foo<98>,
Foo<99>,
Foo<100>>::type::exports x39;
// Avoid annoying "unused variable" warnings.
std::cerr << &x39;
};
} // namespace internal
} // namespace acsdkManufactory
} // namespace alexaClientSDK