blob: d991462b13c30d788ca054953315966695cffcd7 [file] [log] [blame]
// Copyright 2018 The Dawn 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;
static const float dummyConstSuccess = 42.0f;
// Result<void, E*>
// 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());
}
// Result<T*, E*>
// 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);
}
// Tests converting from a Result<TChild*, E*>
TEST(ResultBothPointer, ConversionFromChildClass) {
struct T {
int a;
};
struct TChild : T {};
TChild child;
T* childAsT = &child;
{
Result<T*, int*> result(&child);
TestSuccess(&result, childAsT);
}
{
Result<TChild*, int*> resultChild(&child);
Result<T*, int*> result(std::move(resultChild));
TestSuccess(&result, childAsT);
}
{
Result<TChild*, int*> resultChild(&child);
Result<T*, int*> result = std::move(resultChild);
TestSuccess(&result, childAsT);
}
}
// Result<const T*, E*>
// Test constructing an error Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ConstructingError) {
Result<const float*, int*> result(&dummyError);
TestError(&result, &dummyError);
}
// Test moving an error Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, MovingError) {
Result<const float*, int*> result(&dummyError);
Result<const float*, int*> movedResult(std::move(result));
TestError(&movedResult, &dummyError);
}
// Test returning an error Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ReturningError) {
auto CreateError = []() -> Result<const float*, int*> { return {&dummyError}; };
Result<const float*, int*> result = CreateError();
TestError(&result, &dummyError);
}
// Test constructing a success Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ConstructingSuccess) {
Result<const float*, int*> result(&dummyConstSuccess);
TestSuccess(&result, &dummyConstSuccess);
}
// Test moving a success Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, MovingSuccess) {
Result<const float*, int*> result(&dummyConstSuccess);
Result<const float*, int*> movedResult(std::move(result));
TestSuccess(&movedResult, &dummyConstSuccess);
}
// Test returning a success Result<const T*, E*>
TEST(ResultBothPointerWithConstResult, ReturningSuccess) {
auto CreateSuccess = []() -> Result<const float*, int*> { return {&dummyConstSuccess}; };
Result<const float*, int*> result = CreateSuccess();
TestSuccess(&result, &dummyConstSuccess);
}
// Result<T, E>
// Test constructing an error Result<T, E>
TEST(ResultGeneric, ConstructingError) {
Result<std::vector<float>, int*> result(&dummyError);
TestError(&result, &dummyError);
}
// Test moving an error Result<T, E>
TEST(ResultGeneric, MovingError) {
Result<std::vector<float>, int*> result(&dummyError);
Result<std::vector<float>, int*> movedResult(std::move(result));
TestError(&movedResult, &dummyError);
}
// Test returning an error Result<T, E>
TEST(ResultGeneric, ReturningError) {
auto CreateError = []() -> Result<std::vector<float>, int*> {
return {&dummyError};
};
Result<std::vector<float>, int*> result = CreateError();
TestError(&result, &dummyError);
}
// Test constructing a success Result<T, E>
TEST(ResultGeneric, ConstructingSuccess) {
Result<std::vector<float>, int*> result({1.0f});
TestSuccess(&result, {1.0f});
}
// Test moving a success Result<T, E>
TEST(ResultGeneric, MovingSuccess) {
Result<std::vector<float>, int*> result({1.0f});
Result<std::vector<float>, int*> movedResult(std::move(result));
TestSuccess(&movedResult, {1.0f});
}
// Test returning a success Result<T, E>
TEST(ResultGeneric, ReturningSuccess) {
auto CreateSuccess = []() -> Result<std::vector<float>, int*> {
return {{1.0f}};
};
Result<std::vector<float>, int*> result = CreateSuccess();
TestSuccess(&result, {1.0f});
}
} // anonymous namespace