Consolidate unittests in one binary

This commit is contained in:
Corentin Wallez
2017-05-16 20:16:56 +02:00
committed by Corentin Wallez
parent 314f3852a3
commit 0a58812f34
14 changed files with 24 additions and 73 deletions

View File

@@ -120,16 +120,3 @@ if (APPLE)
endif()
target_include_directories(nxt_backend PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
SetCXX14(nxt_backend)
add_executable(backend_unittests
${TESTS_DIR}/BitSetIteratorTests.cpp
${TESTS_DIR}/CommandAllocatorTests.cpp
${TESTS_DIR}/MathTests.cpp
${TESTS_DIR}/PerStageTests.cpp
${TESTS_DIR}/RefCountedTests.cpp
${TESTS_DIR}/ToBackendTests.cpp
${TESTS_DIR}/UnittestsMain.cpp
)
target_link_libraries(backend_unittests nxt_backend gtest)
target_include_directories(backend_unittests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
SetCXX14(backend_unittests)

View File

@@ -1,85 +0,0 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
#include <gtest/gtest.h>
#include "common/BitSetIterator.h"
// This is ANGLE's BitSetIterator_unittests.cpp file.
using namespace backend;
class BitSetIteratorTest : public testing::Test {
protected:
std::bitset<40> mStateBits;
};
// Simple iterator test.
TEST_F(BitSetIteratorTest, Iterator) {
std::set<unsigned long> originalValues;
originalValues.insert(2);
originalValues.insert(6);
originalValues.insert(8);
originalValues.insert(35);
for (unsigned long value : originalValues) {
mStateBits.set(value);
}
std::set<unsigned long> readValues;
for (unsigned long bit : IterateBitSet(mStateBits)) {
EXPECT_EQ(1u, originalValues.count(bit));
EXPECT_EQ(0u, readValues.count(bit));
readValues.insert(bit);
}
EXPECT_EQ(originalValues.size(), readValues.size());
}
// Test an empty iterator.
TEST_F(BitSetIteratorTest, EmptySet) {
// We don't use the FAIL gtest macro here since it returns immediately,
// causing an unreachable code warning in MSVS
bool sawBit = false;
for (unsigned long bit : IterateBitSet(mStateBits)) {
sawBit = true;
}
EXPECT_FALSE(sawBit);
}
// Test iterating a result of combining two bitsets.
TEST_F(BitSetIteratorTest, NonLValueBitset) {
std::bitset<40> otherBits;
mStateBits.set(1);
mStateBits.set(2);
mStateBits.set(3);
mStateBits.set(4);
otherBits.set(0);
otherBits.set(1);
otherBits.set(3);
otherBits.set(5);
std::set<unsigned long> seenBits;
for (unsigned long bit : IterateBitSet(mStateBits & otherBits)) {
EXPECT_EQ(0u, seenBits.count(bit));
seenBits.insert(bit);
EXPECT_TRUE(mStateBits[bit]);
EXPECT_TRUE(otherBits[bit]);
}
EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());
}

View File

@@ -1,361 +0,0 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
#include <gtest/gtest.h>
#include "common/CommandAllocator.h"
using namespace backend;
// Definition of the command types used in the tests
enum class CommandType {
Draw,
Pipeline,
PushConstants,
Big,
Small,
};
struct CommandDraw {
uint32_t first;
uint32_t count;
};
struct CommandPipeline {
uint64_t pipeline;
uint32_t attachmentPoint;
};
struct CommandPushConstants {
uint8_t size;
uint8_t offset;
};
constexpr int kBigBufferSize = 65536;
struct CommandBig {
uint32_t buffer[kBigBufferSize];
};
struct CommandSmall {
uint16_t data;
};
// Test allocating nothing works
TEST(CommandAllocator, DoNothingAllocator) {
CommandAllocator allocator;
}
// Test iterating over nothing works
TEST(CommandAllocator, DoNothingAllocatorWithIterator) {
CommandAllocator allocator;
CommandIterator iterator(std::move(allocator));
iterator.DataWasDestroyed();
}
// Test basic usage of allocator + iterator
TEST(CommandAllocator, Basic) {
CommandAllocator allocator;
uint64_t myPipeline = 0xDEADBEEFBEEFDEAD;
uint32_t myAttachmentPoint = 2;
uint32_t myFirst = 42;
uint32_t myCount = 16;
{
CommandPipeline* pipeline = allocator.Allocate<CommandPipeline>(CommandType::Pipeline);
pipeline->pipeline = myPipeline;
pipeline->attachmentPoint = myAttachmentPoint;
CommandDraw* draw = allocator.Allocate<CommandDraw>(CommandType::Draw);
draw->first = myFirst;
draw->count = myCount;
}
{
CommandIterator iterator(std::move(allocator));
CommandType type;
bool hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::Pipeline);
CommandPipeline* pipeline = iterator.NextCommand<CommandPipeline>();
ASSERT_EQ(pipeline->pipeline, myPipeline);
ASSERT_EQ(pipeline->attachmentPoint, myAttachmentPoint);
hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::Draw);
CommandDraw* draw = iterator.NextCommand<CommandDraw>();
ASSERT_EQ(draw->first, myFirst);
ASSERT_EQ(draw->count, myCount);
hasNext = iterator.NextCommandId(&type);
ASSERT_FALSE(hasNext);
iterator.DataWasDestroyed();
}
}
// Test basic usage of allocator + iterator with data
TEST(CommandAllocator, BasicWithData) {
CommandAllocator allocator;
uint8_t mySize = 8;
uint8_t myOffset = 3;
uint32_t myValues[5] = {6, 42, 0xFFFFFFFF, 0, 54};
{
CommandPushConstants* pushConstants = allocator.Allocate<CommandPushConstants>(CommandType::PushConstants);
pushConstants->size = mySize;
pushConstants->offset = myOffset;
uint32_t* values = allocator.AllocateData<uint32_t>(5);
for (size_t i = 0; i < 5; i++) {
values[i] = myValues[i];
}
}
{
CommandIterator iterator(std::move(allocator));
CommandType type;
bool hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::PushConstants);
CommandPushConstants* pushConstants = iterator.NextCommand<CommandPushConstants>();
ASSERT_EQ(pushConstants->size, mySize);
ASSERT_EQ(pushConstants->offset, myOffset);
uint32_t* values = iterator.NextData<uint32_t>(5);
for (size_t i = 0; i < 5; i++) {
ASSERT_EQ(values[i], myValues[i]);
}
hasNext = iterator.NextCommandId(&type);
ASSERT_FALSE(hasNext);
iterator.DataWasDestroyed();
}
}
// Test basic iterating several times
TEST(CommandAllocator, MultipleIterations) {
CommandAllocator allocator;
uint32_t myFirst = 42;
uint32_t myCount = 16;
CommandDraw* draw = allocator.Allocate<CommandDraw>(CommandType::Draw);
draw->first = myFirst;
draw->count = myCount;
{
CommandIterator iterator(std::move(allocator));
CommandType type;
// First iteration
bool hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::Draw);
CommandDraw* draw = iterator.NextCommand<CommandDraw>();
ASSERT_EQ(draw->first, myFirst);
ASSERT_EQ(draw->count, myCount);
hasNext = iterator.NextCommandId(&type);
ASSERT_FALSE(hasNext);
// Second iteration
hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::Draw);
draw = iterator.NextCommand<CommandDraw>();
ASSERT_EQ(draw->first, myFirst);
ASSERT_EQ(draw->count, myCount);
hasNext = iterator.NextCommandId(&type);
ASSERT_FALSE(hasNext);
iterator.DataWasDestroyed();
}
}
// Test large commands work
TEST(CommandAllocator, LargeCommands) {
CommandAllocator allocator;
const int kCommandCount = 5;
int count = 0;
for (int i = 0; i < kCommandCount; i++) {
CommandBig* big = allocator.Allocate<CommandBig>(CommandType::Big);
for (int j = 0; j < kBigBufferSize; j++) {
big->buffer[j] = count ++;
}
}
CommandIterator iterator(std::move(allocator));
CommandType type;
count = 0;
int numCommands = 0;
while (iterator.NextCommandId(&type)) {
ASSERT_EQ(type, CommandType::Big);
CommandBig* big = iterator.NextCommand<CommandBig>();
for (int i = 0; i < kBigBufferSize; i++) {
ASSERT_EQ(big->buffer[i], count);
count ++;
}
numCommands ++;
}
ASSERT_EQ(numCommands, kCommandCount);
iterator.DataWasDestroyed();
}
// Test many small commands work
TEST(CommandAllocator, ManySmallCommands) {
CommandAllocator allocator;
// Stay under max representable uint16_t
const int kCommandCount = 50000;
int count = 0;
for (int i = 0; i < kCommandCount; i++) {
CommandSmall* small = allocator.Allocate<CommandSmall>(CommandType::Small);
small->data = count ++;
}
CommandIterator iterator(std::move(allocator));
CommandType type;
count = 0;
int numCommands = 0;
while (iterator.NextCommandId(&type)) {
ASSERT_EQ(type, CommandType::Small);
CommandSmall* small = iterator.NextCommand<CommandSmall>();
ASSERT_EQ(small->data, count);
count ++;
numCommands ++;
}
ASSERT_EQ(numCommands, kCommandCount);
iterator.DataWasDestroyed();
}
// ________
// / \
// | POUIC! |
// \_ ______/
// v
// ()_()
// (O.o)
// (> <)o
// Test usage of iterator.Reset
TEST(CommandAllocator, IteratorReset) {
CommandAllocator allocator;
uint64_t myPipeline = 0xDEADBEEFBEEFDEAD;
uint32_t myAttachmentPoint = 2;
uint32_t myFirst = 42;
uint32_t myCount = 16;
{
CommandPipeline* pipeline = allocator.Allocate<CommandPipeline>(CommandType::Pipeline);
pipeline->pipeline = myPipeline;
pipeline->attachmentPoint = myAttachmentPoint;
CommandDraw* draw = allocator.Allocate<CommandDraw>(CommandType::Draw);
draw->first = myFirst;
draw->count = myCount;
}
{
CommandIterator iterator(std::move(allocator));
CommandType type;
bool hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::Pipeline);
CommandPipeline* pipeline = iterator.NextCommand<CommandPipeline>();
ASSERT_EQ(pipeline->pipeline, myPipeline);
ASSERT_EQ(pipeline->attachmentPoint, myAttachmentPoint);
iterator.Reset();
hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::Pipeline);
pipeline = iterator.NextCommand<CommandPipeline>();
ASSERT_EQ(pipeline->pipeline, myPipeline);
ASSERT_EQ(pipeline->attachmentPoint, myAttachmentPoint);
hasNext = iterator.NextCommandId(&type);
ASSERT_TRUE(hasNext);
ASSERT_EQ(type, CommandType::Draw);
CommandDraw* draw = iterator.NextCommand<CommandDraw>();
ASSERT_EQ(draw->first, myFirst);
ASSERT_EQ(draw->count, myCount);
hasNext = iterator.NextCommandId(&type);
ASSERT_FALSE(hasNext);
iterator.DataWasDestroyed();
}
}
// Test iterating empty iterators
TEST(CommandAllocator, EmptyIterator) {
{
CommandAllocator allocator;
CommandIterator iterator(std::move(allocator));
CommandType type;
bool hasNext = iterator.NextCommandId(&type);
ASSERT_FALSE(hasNext);
iterator.DataWasDestroyed();
}
{
CommandAllocator allocator;
CommandIterator iterator1(std::move(allocator));
CommandIterator iterator2(std::move(iterator1));
CommandType type;
bool hasNext = iterator2.NextCommandId(&type);
ASSERT_FALSE(hasNext);
iterator1.DataWasDestroyed();
iterator2.DataWasDestroyed();
}
{
CommandIterator iterator1;
CommandIterator iterator2(std::move(iterator1));
CommandType type;
bool hasNext = iterator2.NextCommandId(&type);
ASSERT_FALSE(hasNext);
iterator1.DataWasDestroyed();
iterator2.DataWasDestroyed();
}
}

View File

@@ -1,85 +0,0 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
#include <gtest/gtest.h>
#include "common/Math.h"
using namespace backend;
// Tests for ScanForward
TEST(Math, ScanForward) {
// Test extrema
ASSERT_EQ(ScanForward(1), 0);
ASSERT_EQ(ScanForward(0x8000000000000000), 63);
// Test with more than one bit set.
ASSERT_EQ(ScanForward(256), 8);
ASSERT_EQ(ScanForward(256 + 32), 5);
ASSERT_EQ(ScanForward(1024 + 256 + 32), 5);
}
// Tests for Log2
TEST(Math, Log2) {
// Test extrema
ASSERT_EQ(Log2(1), 0);
ASSERT_EQ(Log2(0xFFFFFFFF), 31);
// Test boundary between two logs
ASSERT_EQ(Log2(0x80000000), 31);
ASSERT_EQ(Log2(0x7FFFFFFF), 30);
ASSERT_EQ(Log2(16), 4);
ASSERT_EQ(Log2(15), 3);
}
// Tests for IsPowerOfTwo
TEST(Math, IsPowerOfTwo) {
ASSERT_TRUE(IsPowerOfTwo(1));
ASSERT_TRUE(IsPowerOfTwo(2));
ASSERT_FALSE(IsPowerOfTwo(3));
ASSERT_TRUE(IsPowerOfTwo(0x8000000));
ASSERT_FALSE(IsPowerOfTwo(0x8000400));
}
// Tests for Align
TEST(Math, Align) {
constexpr size_t kTestAlignment = 8;
char buffer[kTestAlignment * 4];
for (size_t i = 0; i < 2 * kTestAlignment; ++i) {
char* unaligned = &buffer[i];
char* aligned = Align(unaligned, kTestAlignment);
ASSERT_GE(aligned - unaligned, 0);
ASSERT_LT(aligned - unaligned, kTestAlignment);
ASSERT_EQ(reinterpret_cast<intptr_t>(aligned) & (kTestAlignment -1), 0);
}
}
// Tests for IsAligned
TEST(Math, IsAligned) {
constexpr size_t kTestAlignment = 8;
char buffer[kTestAlignment * 4];
for (size_t i = 0; i < 2 * kTestAlignment; ++i) {
char* unaligned = &buffer[i];
char* aligned = Align(unaligned, kTestAlignment);
ASSERT_EQ(IsAligned(unaligned, kTestAlignment), unaligned == aligned);
}
}

View File

@@ -1,89 +0,0 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
#include <gtest/gtest.h>
#include "common/PerStage.h"
using namespace backend;
// Tests for StageBit
TEST(PerStage, StageBit) {
ASSERT_EQ(StageBit(nxt::ShaderStage::Vertex), nxt::ShaderStageBit::Vertex);
ASSERT_EQ(StageBit(nxt::ShaderStage::Fragment), nxt::ShaderStageBit::Fragment);
ASSERT_EQ(StageBit(nxt::ShaderStage::Compute), nxt::ShaderStageBit::Compute);
}
// Basic test for the PerStage container
TEST(PerStage, PerStage) {
PerStage<int> data;
// Store data using nxt::ShaderStage
data[nxt::ShaderStage::Vertex] = 42;
data[nxt::ShaderStage::Fragment] = 3;
data[nxt::ShaderStage::Compute] = -1;
// Load it using nxt::ShaderStageBit
ASSERT_EQ(data[nxt::ShaderStageBit::Vertex], 42);
ASSERT_EQ(data[nxt::ShaderStageBit::Fragment], 3);
ASSERT_EQ(data[nxt::ShaderStageBit::Compute], -1);
}
// Test IterateStages with kAllStages
TEST(PerStage, IterateAllStages) {
PerStage<int> counts;
counts[nxt::ShaderStage::Vertex] = 0;
counts[nxt::ShaderStage::Fragment] = 0;
counts[nxt::ShaderStage::Compute] = 0;
for (auto stage : IterateStages(kAllStages)) {
counts[stage] ++;
}
ASSERT_EQ(counts[nxt::ShaderStageBit::Vertex], 1);
ASSERT_EQ(counts[nxt::ShaderStageBit::Fragment], 1);
ASSERT_EQ(counts[nxt::ShaderStageBit::Compute], 1);
}
// Test IterateStages with one stage
TEST(PerStage, IterateOneStage) {
PerStage<int> counts;
counts[nxt::ShaderStage::Vertex] = 0;
counts[nxt::ShaderStage::Fragment] = 0;
counts[nxt::ShaderStage::Compute] = 0;
for (auto stage : IterateStages(nxt::ShaderStageBit::Fragment)) {
counts[stage] ++;
}
ASSERT_EQ(counts[nxt::ShaderStageBit::Vertex], 0);
ASSERT_EQ(counts[nxt::ShaderStageBit::Fragment], 1);
ASSERT_EQ(counts[nxt::ShaderStageBit::Compute], 0);
}
// Test IterateStages with no stage
TEST(PerStage, IterateNoStages) {
PerStage<int> counts;
counts[nxt::ShaderStage::Vertex] = 0;
counts[nxt::ShaderStage::Fragment] = 0;
counts[nxt::ShaderStage::Compute] = 0;
for (auto stage : IterateStages(nxt::ShaderStageBit::Fragment & nxt::ShaderStageBit::Vertex)) {
counts[stage] ++;
}
ASSERT_EQ(counts[nxt::ShaderStageBit::Vertex], 0);
ASSERT_EQ(counts[nxt::ShaderStageBit::Fragment], 0);
ASSERT_EQ(counts[nxt::ShaderStageBit::Compute], 0);
}

View File

@@ -1,178 +0,0 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
#include <gtest/gtest.h>
#include "common/RefCounted.h"
using namespace backend;
struct RCTest : public RefCounted {
RCTest() {
}
RCTest(bool* deleted): deleted(deleted) {
}
~RCTest() override {
if (deleted != nullptr) {
*deleted = true;
}
}
RCTest* GetThis() {
return this;
}
bool* deleted = nullptr;
};
// Test that RCs start with one external ref, and removing it destroys the object.
TEST(RefCounted, StartsWithOneExternalRef) {
bool deleted = false;
auto test = new RCTest(&deleted);
test->Release();
ASSERT_TRUE(deleted);
}
// Test internal refs keep the RC alive.
TEST(RefCounted, InternalRefKeepsAlive) {
bool deleted = false;
auto test = new RCTest(&deleted);
test->ReferenceInternal();
test->Release();
ASSERT_FALSE(deleted);
test->ReleaseInternal();
ASSERT_TRUE(deleted);
}
// Test Ref remove internal reference when going out of scope
TEST(Ref, EndOfScopeRemovesInternalRef) {
bool deleted = false;
{
Ref<RCTest> test(new RCTest(&deleted));
test->Release();
}
ASSERT_TRUE(deleted);
}
// Test getting pointer out of the Ref
TEST(Ref, Gets) {
RCTest* original = new RCTest;
Ref<RCTest> test(original);
test->Release();
ASSERT_EQ(test.Get(), original);
ASSERT_EQ(&*test, original);
ASSERT_EQ(test->GetThis(), original);
}
// Test Refs default to null
TEST(Ref, DefaultsToNull) {
Ref<RCTest> test;
ASSERT_EQ(test.Get(), nullptr);
ASSERT_EQ(&*test, nullptr);
ASSERT_EQ(test->GetThis(), nullptr);
}
// Test Refs can be used inside ifs
TEST(Ref, BoolConversion) {
Ref<RCTest> empty;
Ref<RCTest> full(new RCTest);
full->Release();
if (!full || empty) {
ASSERT_TRUE(false);
}
}
// Test Ref's copy constructor
TEST(Ref, CopyConstructor) {
bool deleted;
RCTest* original = new RCTest(&deleted);
Ref<RCTest> source(original);
Ref<RCTest> destination(source);
original->Release();
ASSERT_EQ(source.Get(), original);
ASSERT_EQ(destination.Get(), original);
source = nullptr;
ASSERT_FALSE(deleted);
destination = nullptr;
ASSERT_TRUE(deleted);
}
// Test Ref's copy assignment
TEST(Ref, CopyAssignment) {
bool deleted;
RCTest* original = new RCTest(&deleted);
Ref<RCTest> source(original);
original->Release();
Ref<RCTest> destination;
destination = source;
ASSERT_EQ(source.Get(), original);
ASSERT_EQ(destination.Get(), original);
source = nullptr;
// This fails when address sanitizer is turned on
ASSERT_FALSE(deleted);
destination = nullptr;
ASSERT_TRUE(deleted);
}
// Test Ref's move constructor
TEST(Ref, MoveConstructor) {
bool deleted;
RCTest* original = new RCTest(&deleted);
Ref<RCTest> source(original);
Ref<RCTest> destination(std::move(source));
original->Release();
ASSERT_EQ(source.Get(), nullptr);
ASSERT_EQ(destination.Get(), original);
ASSERT_FALSE(deleted);
destination = nullptr;
ASSERT_TRUE(deleted);
}
// Test Ref's move assignment
TEST(Ref, MoveAssignment) {
bool deleted;
RCTest* original = new RCTest(&deleted);
Ref<RCTest> source(original);
original->Release();
Ref<RCTest> destination;
destination = std::move(source);
ASSERT_EQ(source.Get(), nullptr);
ASSERT_EQ(destination.Get(), original);
ASSERT_FALSE(deleted);
destination = nullptr;
ASSERT_TRUE(deleted);
}

View File

@@ -1,89 +0,0 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
#include <gtest/gtest.h>
#include "common/RefCounted.h"
#include "common/ToBackend.h"
#include <type_traits>
// Make our own Base - Backend object pair, reusing the CommandBuffer name
namespace backend {
class CommandBufferBase : public RefCounted {
};
}
using namespace backend;
class MyCommandBuffer : public CommandBufferBase {
};
struct MyBackendTraits {
using CommandBufferType = MyCommandBuffer;
};
// Instanciate ToBackend for our "backend"
template<typename T>
auto ToBackend(T&& common) -> decltype(ToBackendBase<MyBackendTraits>(common)) {
return ToBackendBase<MyBackendTraits>(common);
}
// Test that ToBackend correctly converts pointers to base classes.
TEST(ToBackend, Pointers) {
{
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
const CommandBufferBase* base = cmdBuf;
auto backendCmdBuf = ToBackend(base);
static_assert(std::is_same<decltype(backendCmdBuf), const MyCommandBuffer*>::value, "");
ASSERT_EQ(cmdBuf, backendCmdBuf);
cmdBuf->Release();
}
{
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
CommandBufferBase* base = cmdBuf;
auto backendCmdBuf = ToBackend(base);
static_assert(std::is_same<decltype(backendCmdBuf), MyCommandBuffer*>::value, "");
ASSERT_EQ(cmdBuf, backendCmdBuf);
cmdBuf->Release();
}
}
// Test that ToBackend correctly converts Refs to base classes.
TEST(ToBackend, Ref) {
{
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
const Ref<CommandBufferBase> base(cmdBuf);
const auto& backendCmdBuf = ToBackend(base);
static_assert(std::is_same<decltype(ToBackend(base)), const Ref<MyCommandBuffer>&>::value, "");
ASSERT_EQ(cmdBuf, backendCmdBuf.Get());
cmdBuf->Release();
}
{
MyCommandBuffer* cmdBuf = new MyCommandBuffer;
Ref<CommandBufferBase> base(cmdBuf);
auto backendCmdBuf = ToBackend(base);
static_assert(std::is_same<decltype(ToBackend(base)), Ref<MyCommandBuffer>&>::value, "");
ASSERT_EQ(cmdBuf, backendCmdBuf.Get());
cmdBuf->Release();
}
}

View File

@@ -1,20 +0,0 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License 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.
#include <gtest/gtest.h>
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}