mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 16:37:08 +00:00
Add a functional-y Result<T, E> class and tests for it.
Implements two optimized versions of Result, one for Result<void, E*> as a nullable pointer, and one for Result<T*, E*> as a tagged pointer.
This commit is contained in:
committed by
Corentin Wallez
parent
2141e960b7
commit
44b5ca4aa1
@@ -37,6 +37,7 @@ list(APPEND UNITTEST_SOURCES
|
||||
${UNITTESTS_DIR}/ObjectBaseTests.cpp
|
||||
${UNITTESTS_DIR}/PerStageTests.cpp
|
||||
${UNITTESTS_DIR}/RefCountedTests.cpp
|
||||
${UNITTESTS_DIR}/ResultTests.cpp
|
||||
${UNITTESTS_DIR}/SerialQueueTests.cpp
|
||||
${UNITTESTS_DIR}/ToBackendTests.cpp
|
||||
${UNITTESTS_DIR}/WireTests.cpp
|
||||
|
||||
137
src/tests/unittests/ResultTests.cpp
Normal file
137
src/tests/unittests/ResultTests.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright 2018 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/Result.h"
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T, typename E>
|
||||
void TestError(Result<T, E>* result, E expectedError) {
|
||||
ASSERT_TRUE(result->IsError());
|
||||
ASSERT_FALSE(result->IsSuccess());
|
||||
|
||||
E storedError = result->AcquireError();
|
||||
ASSERT_EQ(storedError, expectedError);
|
||||
}
|
||||
|
||||
template<typename T, typename E>
|
||||
void TestSuccess(Result<T, E>* result, T expectedSuccess) {
|
||||
ASSERT_FALSE(result->IsError());
|
||||
ASSERT_TRUE(result->IsSuccess());
|
||||
|
||||
T storedSuccess = result->AcquireSuccess();
|
||||
ASSERT_EQ(storedSuccess, expectedSuccess);
|
||||
}
|
||||
|
||||
static int dummyError = 0xbeef;
|
||||
static float dummySuccess = 42.0f;
|
||||
|
||||
// Test constructing an error Result<void, E*>
|
||||
TEST(ResultOnlyPointerError, ConstructingError) {
|
||||
Result<void, int*> result(&dummyError);
|
||||
TestError(&result, &dummyError);
|
||||
}
|
||||
|
||||
// Test moving an error Result<void, E*>
|
||||
TEST(ResultOnlyPointerError, MovingError) {
|
||||
Result<void, int*> result(&dummyError);
|
||||
Result<void, int*> movedResult(std::move(result));
|
||||
TestError(&movedResult, &dummyError);
|
||||
}
|
||||
|
||||
// Test returning an error Result<void, E*>
|
||||
TEST(ResultOnlyPointerError, ReturningError) {
|
||||
auto CreateError = []() -> Result<void, int*> {
|
||||
return {&dummyError};
|
||||
};
|
||||
|
||||
Result<void, int*> result = CreateError();
|
||||
TestError(&result, &dummyError);
|
||||
}
|
||||
|
||||
// Test constructing a success Result<void, E*>
|
||||
TEST(ResultOnlyPointerError, ConstructingSuccess) {
|
||||
Result<void, int*> result;
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
ASSERT_FALSE(result.IsError());
|
||||
}
|
||||
|
||||
// Test moving a success Result<void, E*>
|
||||
TEST(ResultOnlyPointerError, MovingSuccess) {
|
||||
Result<void, int*> result;
|
||||
Result<void, int*> movedResult(std::move(result));
|
||||
ASSERT_TRUE(movedResult.IsSuccess());
|
||||
ASSERT_FALSE(movedResult.IsError());
|
||||
}
|
||||
|
||||
// Test returning a success Result<void, E*>
|
||||
TEST(ResultOnlyPointerError, ReturningSuccess) {
|
||||
auto CreateError = []() -> Result<void, int*> {
|
||||
return {};
|
||||
};
|
||||
|
||||
Result<void, int*> result = CreateError();
|
||||
ASSERT_TRUE(result.IsSuccess());
|
||||
ASSERT_FALSE(result.IsError());
|
||||
}
|
||||
|
||||
// Test constructing an error Result<T*, E*>
|
||||
TEST(ResultBothPointer, ConstructingError) {
|
||||
Result<float*, int*> result(&dummyError);
|
||||
TestError(&result, &dummyError);
|
||||
}
|
||||
|
||||
// Test moving an error Result<T*, E*>
|
||||
TEST(ResultBothPointer, MovingError) {
|
||||
Result<float*, int*> result(&dummyError);
|
||||
Result<float*, int*> movedResult(std::move(result));
|
||||
TestError(&movedResult, &dummyError);
|
||||
}
|
||||
|
||||
// Test returning an error Result<T*, E*>
|
||||
TEST(ResultBothPointer, ReturningError) {
|
||||
auto CreateError = []() -> Result<float*, int*> {
|
||||
return {&dummyError};
|
||||
};
|
||||
|
||||
Result<float*, int*> result = CreateError();
|
||||
TestError(&result, &dummyError);
|
||||
}
|
||||
|
||||
// Test constructing a success Result<T*, E*>
|
||||
TEST(ResultBothPointer, ConstructingSuccess) {
|
||||
Result<float*, int*> result(&dummySuccess);
|
||||
TestSuccess(&result, &dummySuccess);
|
||||
}
|
||||
|
||||
// Test moving a success Result<T*, E*>
|
||||
TEST(ResultBothPointer, MovingSuccess) {
|
||||
Result<float*, int*> result(&dummySuccess);
|
||||
Result<float*, int*> movedResult(std::move(result));
|
||||
TestSuccess(&movedResult, &dummySuccess);
|
||||
}
|
||||
|
||||
// Test returning a success Result<T*, E*>
|
||||
TEST(ResultBothPointer, ReturningSuccess) {
|
||||
auto CreateSuccess = []() -> Result<float*, int*> {
|
||||
return {&dummySuccess};
|
||||
};
|
||||
|
||||
Result<float*, int*> result = CreateSuccess();
|
||||
TestSuccess(&result, &dummySuccess);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
Reference in New Issue
Block a user