mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-27 02:01:42 +00:00
Add unit tests for StringValue and Value.
Add unit test framework to CMakeLists.txt. Fix a couple of bugs found by unit tests. Change-Id: I2092a7f0570fae0f19f9e083c4837ccefcc4ca1a
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(NetworkTables)
|
||||
project(ntcore)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wformat=2 -Wall -Wextra -Werror -pedantic -Wno-unused-parameter")
|
||||
|
||||
@@ -10,6 +10,48 @@ add_library(ntcore STATIC ${SRC_SHARE_FILES} ${SRC_TARGET_FILES})
|
||||
target_link_libraries(ntcore)
|
||||
INSTALL(TARGETS ntcore ARCHIVE DESTINATION lib COMPONENT lib)
|
||||
INSTALL(DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT headers)
|
||||
# lib/ c gcc_s ld-linux
|
||||
# usr/lib stdc++
|
||||
# NiRioSrv
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# We need thread support
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# Enable ExternalProject CMake module
|
||||
include(ExternalProject)
|
||||
|
||||
# Download and install GoogleMock
|
||||
ExternalProject_Add(
|
||||
gmock
|
||||
URL https://googlemock.googlecode.com/files/gmock-1.7.0.zip
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gmock
|
||||
# Disable install step
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
# Create a libgmock target to be used as a dependency by test programs
|
||||
add_library(libgmock IMPORTED STATIC GLOBAL)
|
||||
add_dependencies(libgmock gmock)
|
||||
add_library(libgtest IMPORTED STATIC GLOBAL)
|
||||
add_dependencies(libgtest gmock)
|
||||
|
||||
# Set gmock properties
|
||||
ExternalProject_Get_Property(gmock source_dir binary_dir)
|
||||
set_target_properties(libgmock PROPERTIES
|
||||
"IMPORTED_LOCATION" "${binary_dir}/libgmock.a"
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
|
||||
# "INTERFACE_INCLUDE_DIRECTORIES" "${source_dir}/include"
|
||||
)
|
||||
set_target_properties(libgtest PROPERTIES
|
||||
"IMPORTED_LOCATION" "${binary_dir}/gtest/libgtest.a"
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
|
||||
# "INTERFACE_INCLUDE_DIRECTORIES" "${source_dir}/include"
|
||||
)
|
||||
# I couldn't make it work with INTERFACE_INCLUDE_DIRECTORIES
|
||||
include_directories("${source_dir}/include")
|
||||
include_directories("${source_dir}/gtest/include")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
|
||||
@@ -40,24 +40,6 @@ void Value::SetBooleanArray(llvm::ArrayRef<int> value) {
|
||||
std::copy(value.begin(), value.end(), data.arr_boolean.arr);
|
||||
}
|
||||
|
||||
void Value::SetBooleanArray(llvm::ArrayRef<bool> value) {
|
||||
// handle type change
|
||||
if (NT_Value::type != NT_BOOLEAN_ARRAY) {
|
||||
NT_DisposeValue(this);
|
||||
data.arr_boolean.arr = nullptr;
|
||||
data.arr_boolean.size = 0; // set to zero so size change is hit below
|
||||
NT_Value::type = NT_BOOLEAN_ARRAY;
|
||||
}
|
||||
// handle size change
|
||||
if (data.arr_boolean.size != value.size()) {
|
||||
std::free(data.arr_boolean.arr);
|
||||
data.arr_boolean.arr =
|
||||
static_cast<int*>(std::malloc(value.size()*sizeof(int)));
|
||||
data.arr_boolean.size = value.size();
|
||||
}
|
||||
std::copy(value.begin(), value.end(), data.arr_boolean.arr);
|
||||
}
|
||||
|
||||
void Value::SetDoubleArray(llvm::ArrayRef<double> value) {
|
||||
// handle type change
|
||||
if (NT_Value::type != NT_DOUBLE_ARRAY) {
|
||||
@@ -89,6 +71,11 @@ void Value::SetStringArray(std::vector<StringValue>& value) {
|
||||
std::free(data.arr_string.arr);
|
||||
data.arr_string.arr =
|
||||
static_cast<NT_String*>(std::malloc(value.size()*sizeof(NT_String)));
|
||||
// need to initialize array to avoid invalid frees in std::move below.
|
||||
for (size_t i=0; i<value.size(); ++i) {
|
||||
data.arr_string.arr[i].str = nullptr;
|
||||
data.arr_string.arr[i].len = 0;
|
||||
}
|
||||
data.arr_string.size = value.size();
|
||||
}
|
||||
std::move(value.begin(), value.end(),
|
||||
|
||||
16
src/Value.h
16
src/Value.h
@@ -18,13 +18,16 @@
|
||||
|
||||
namespace ntimpl {
|
||||
|
||||
class StringValueTest;
|
||||
class Storage;
|
||||
class Value;
|
||||
class ValueTest;
|
||||
|
||||
/*
|
||||
* C++ wrapper class around NT_String.
|
||||
*/
|
||||
class StringValue : private NT_String {
|
||||
friend class StringValueTest;
|
||||
friend class Value;
|
||||
public:
|
||||
StringValue() { NT_InitString(this); }
|
||||
@@ -59,6 +62,7 @@ class StringValue : private NT_String {
|
||||
* C++ wrapper class around NT_Value.
|
||||
*/
|
||||
class Value : private NT_Value {
|
||||
friend class ValueTest;
|
||||
friend class Storage;
|
||||
public:
|
||||
Value() { NT_InitValue(this); }
|
||||
@@ -86,8 +90,6 @@ class Value : private NT_Value {
|
||||
assert(NT_Value::type == NT_RAW);
|
||||
return static_cast<const StringValue&>(data.v_raw);
|
||||
}
|
||||
// Ideally this would return llvm::ArrayRef<bool> but the C headers must
|
||||
// use "int" and casting may be very unsafe.
|
||||
llvm::ArrayRef<int> GetBooleanArray() const {
|
||||
assert(NT_Value::type == NT_BOOLEAN_ARRAY);
|
||||
return llvm::ArrayRef<int>(data.arr_boolean.arr, data.arr_boolean.size);
|
||||
@@ -97,7 +99,7 @@ class Value : private NT_Value {
|
||||
return llvm::ArrayRef<double>(data.arr_double.arr, data.arr_double.size);
|
||||
}
|
||||
llvm::ArrayRef<StringValue> GetStringArray() const {
|
||||
assert(NT_Value::type == NT_BOOLEAN_ARRAY);
|
||||
assert(NT_Value::type == NT_STRING_ARRAY);
|
||||
return llvm::ArrayRef<StringValue>(
|
||||
static_cast<StringValue*>(data.arr_string.arr), data.arr_string.size);
|
||||
}
|
||||
@@ -127,7 +129,7 @@ class Value : private NT_Value {
|
||||
data.v_string.len = 0;
|
||||
NT_Value::type = NT_STRING;
|
||||
}
|
||||
data.v_string = value;
|
||||
static_cast<StringValue&>(data.v_string) = std::move(value);
|
||||
}
|
||||
void SetRaw(llvm::StringRef value) { SetRaw(StringValue(value)); }
|
||||
void SetRaw(StringValue&& value) {
|
||||
@@ -137,11 +139,10 @@ class Value : private NT_Value {
|
||||
data.v_raw.len = 0;
|
||||
NT_Value::type = NT_RAW;
|
||||
}
|
||||
data.v_raw = value;
|
||||
static_cast<StringValue&>(data.v_raw) = std::move(value);
|
||||
}
|
||||
|
||||
void SetBooleanArray(llvm::ArrayRef<int> value);
|
||||
void SetBooleanArray(llvm::ArrayRef<bool> value);
|
||||
void SetDoubleArray(llvm::ArrayRef<double> value);
|
||||
|
||||
// Note: This function moves the values out of the vector.
|
||||
@@ -174,6 +175,9 @@ class Value : private NT_Value {
|
||||
};
|
||||
|
||||
bool operator==(const Value& lhs, const Value& rhs);
|
||||
inline bool operator!=(const Value& lhs, const Value& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace ntimpl
|
||||
|
||||
|
||||
1
test/CMakeLists.txt
Normal file
1
test/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_subdirectory(unit)
|
||||
10
test/unit/CMakeLists.txt
Normal file
10
test/unit/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
file(GLOB SRCS *.cpp)
|
||||
|
||||
add_executable(testntcore ${SRCS})
|
||||
|
||||
target_link_libraries(testntcore
|
||||
ntcore
|
||||
libgmock
|
||||
libgtest
|
||||
)
|
||||
|
||||
8
test/unit/main.cpp
Normal file
8
test/unit/main.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
return ret;
|
||||
}
|
||||
52
test/unit/test_StringValue.cpp
Normal file
52
test/unit/test_StringValue.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "Value.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace ntimpl {
|
||||
|
||||
class StringValueTest : public ::testing::Test {
|
||||
public:
|
||||
NT_String& ToNT(StringValue& v) { return v; }
|
||||
};
|
||||
|
||||
TEST_F(StringValueTest, ConstructEmpty) {
|
||||
StringValue v;
|
||||
ASSERT_EQ(ToNT(v).str, nullptr);
|
||||
ASSERT_EQ(ToNT(v).len, 0u);
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, ConstructStringRef) {
|
||||
StringValue v("hello");
|
||||
ASSERT_EQ(llvm::StringRef(v), "hello");
|
||||
ASSERT_EQ(ToNT(v).str, llvm::StringRef("hello"));
|
||||
ASSERT_EQ(ToNT(v).len, 5u);
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, ConstructMove) {
|
||||
StringValue v("hello");
|
||||
char* orig = ToNT(v).str;
|
||||
ASSERT_NE(orig, nullptr);
|
||||
ASSERT_EQ(ToNT(v).len, 5u);
|
||||
StringValue v2(std::move(v));
|
||||
ASSERT_EQ(ToNT(v).str, nullptr);
|
||||
ASSERT_EQ(ToNT(v).len, 0u);
|
||||
ASSERT_EQ(ToNT(v2).str, orig);
|
||||
ASSERT_EQ(ToNT(v2).len, 5u);
|
||||
}
|
||||
|
||||
TEST_F(StringValueTest, AssignMove) {
|
||||
StringValue v("hello");
|
||||
char* orig = ToNT(v).str;
|
||||
ASSERT_NE(orig, nullptr);
|
||||
ASSERT_EQ(ToNT(v).len, 5u);
|
||||
StringValue v2("goodbye");
|
||||
ASSERT_NE(ToNT(v2).str, nullptr);
|
||||
ASSERT_EQ(ToNT(v2).len, 7u);
|
||||
v2 = std::move(v);
|
||||
ASSERT_EQ(ToNT(v).str, nullptr);
|
||||
ASSERT_EQ(ToNT(v).len, 0u);
|
||||
ASSERT_EQ(ToNT(v2).str, orig);
|
||||
ASSERT_EQ(ToNT(v2).len, 5u);
|
||||
}
|
||||
|
||||
} // namespace ntimpl
|
||||
347
test/unit/test_Value.cpp
Normal file
347
test/unit/test_Value.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
#include "Value.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace ntimpl {
|
||||
|
||||
class ValueTest : public ::testing::Test {
|
||||
public:
|
||||
NT_Value& ToNT(Value& v) { return v; }
|
||||
};
|
||||
|
||||
typedef ValueTest ValueDeathTest;
|
||||
|
||||
TEST_F(ValueTest, ConstructEmpty) {
|
||||
Value v;
|
||||
ASSERT_EQ(ToNT(v).type, NT_UNASSIGNED);
|
||||
ASSERT_EQ(ToNT(v).last_change, 0u);
|
||||
ASSERT_EQ(v.type(), NT_UNASSIGNED);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, ConstructMove) {
|
||||
Value v;
|
||||
v.SetString("hello");
|
||||
ASSERT_EQ(v.type(), NT_STRING);
|
||||
Value v2(std::move(v));
|
||||
ASSERT_EQ(v.type(), NT_UNASSIGNED);
|
||||
ASSERT_EQ(v2.type(), NT_STRING);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, AssignMove) {
|
||||
Value v;
|
||||
v.SetString("hello");
|
||||
ASSERT_EQ(v.type(), NT_STRING);
|
||||
Value v2;
|
||||
v2.SetDouble(0.5);
|
||||
ASSERT_EQ(v2.type(), NT_DOUBLE);
|
||||
v2 = std::move(v);
|
||||
ASSERT_EQ(v.type(), NT_UNASSIGNED);
|
||||
ASSERT_EQ(v2.type(), NT_STRING);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, Boolean) {
|
||||
Value v;
|
||||
v.SetBoolean(false);
|
||||
ASSERT_EQ(ToNT(v).type, NT_BOOLEAN);
|
||||
ASSERT_EQ(ToNT(v).data.v_boolean, false);
|
||||
ASSERT_EQ(v.type(), NT_BOOLEAN);
|
||||
ASSERT_EQ(v.GetBoolean(), false);
|
||||
v.SetBoolean(true);
|
||||
ASSERT_EQ(ToNT(v).type, NT_BOOLEAN);
|
||||
ASSERT_EQ(ToNT(v).data.v_boolean, true);
|
||||
ASSERT_EQ(v.type(), NT_BOOLEAN);
|
||||
ASSERT_EQ(v.GetBoolean(), true);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, Double) {
|
||||
Value v;
|
||||
v.SetDouble(0.5);
|
||||
ASSERT_EQ(ToNT(v).type, NT_DOUBLE);
|
||||
ASSERT_EQ(ToNT(v).data.v_double, 0.5);
|
||||
ASSERT_EQ(v.type(), NT_DOUBLE);
|
||||
ASSERT_EQ(v.GetDouble(), 0.5);
|
||||
v.SetDouble(0.25);
|
||||
ASSERT_EQ(ToNT(v).type, NT_DOUBLE);
|
||||
ASSERT_EQ(ToNT(v).data.v_double, 0.25);
|
||||
ASSERT_EQ(v.type(), NT_DOUBLE);
|
||||
ASSERT_EQ(v.GetDouble(), 0.25);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, String) {
|
||||
Value v;
|
||||
v.SetString("hello");
|
||||
ASSERT_EQ(ToNT(v).type, NT_STRING);
|
||||
ASSERT_EQ(ToNT(v).data.v_string.str, llvm::StringRef("hello"));
|
||||
ASSERT_EQ(ToNT(v).data.v_string.len, 5u);
|
||||
ASSERT_EQ(v.type(), NT_STRING);
|
||||
ASSERT_EQ(v.GetString(), "hello");
|
||||
v.SetString("goodbye");
|
||||
ASSERT_EQ(ToNT(v).type, NT_STRING);
|
||||
ASSERT_EQ(ToNT(v).data.v_string.str, llvm::StringRef("goodbye"));
|
||||
ASSERT_EQ(ToNT(v).data.v_string.len, 7u);
|
||||
ASSERT_EQ(v.type(), NT_STRING);
|
||||
ASSERT_EQ(v.GetString(), "goodbye");
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, Raw) {
|
||||
Value v;
|
||||
v.SetRaw("hello");
|
||||
ASSERT_EQ(ToNT(v).type, NT_RAW);
|
||||
ASSERT_EQ(ToNT(v).data.v_string.str, llvm::StringRef("hello"));
|
||||
ASSERT_EQ(ToNT(v).data.v_string.len, 5u);
|
||||
ASSERT_EQ(v.type(), NT_RAW);
|
||||
ASSERT_EQ(v.GetRaw(), "hello");
|
||||
v.SetRaw("goodbye");
|
||||
ASSERT_EQ(ToNT(v).type, NT_RAW);
|
||||
ASSERT_EQ(ToNT(v).data.v_string.str, llvm::StringRef("goodbye"));
|
||||
ASSERT_EQ(ToNT(v).data.v_string.len, 7u);
|
||||
ASSERT_EQ(v.type(), NT_RAW);
|
||||
ASSERT_EQ(v.GetRaw(), "goodbye");
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, BooleanArray) {
|
||||
Value v;
|
||||
std::vector<int> vec{1,0,1};
|
||||
v.SetBooleanArray(vec);
|
||||
ASSERT_EQ(ToNT(v).type, NT_BOOLEAN_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.size, 3u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[0], vec[0]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[1], vec[1]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[2], vec[2]);
|
||||
ASSERT_EQ(v.type(), NT_BOOLEAN_ARRAY);
|
||||
ASSERT_EQ(v.GetBooleanArray(), llvm::ArrayRef<int>(vec));
|
||||
|
||||
// assign with same size
|
||||
vec = {0,1,0};
|
||||
v.SetBooleanArray(vec);
|
||||
ASSERT_EQ(ToNT(v).type, NT_BOOLEAN_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.size, 3u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[0], vec[0]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[1], vec[1]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[2], vec[2]);
|
||||
ASSERT_EQ(v.type(), NT_BOOLEAN_ARRAY);
|
||||
ASSERT_EQ(v.GetBooleanArray(), llvm::ArrayRef<int>(vec));
|
||||
|
||||
// assign with different size
|
||||
vec = {1,0};
|
||||
v.SetBooleanArray(vec);
|
||||
ASSERT_EQ(ToNT(v).type, NT_BOOLEAN_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.size, 2u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[0], vec[0]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_boolean.arr[1], vec[1]);
|
||||
ASSERT_EQ(v.type(), NT_BOOLEAN_ARRAY);
|
||||
ASSERT_EQ(v.GetBooleanArray(), llvm::ArrayRef<int>(vec));
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, DoubleArray) {
|
||||
Value v;
|
||||
std::vector<double> vec{0.5,0.25,0.5};
|
||||
v.SetDoubleArray(vec);
|
||||
ASSERT_EQ(ToNT(v).type, NT_DOUBLE_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.size, 3u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[0], vec[0]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[1], vec[1]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[2], vec[2]);
|
||||
ASSERT_EQ(v.type(), NT_DOUBLE_ARRAY);
|
||||
ASSERT_EQ(v.GetDoubleArray(), llvm::ArrayRef<double>(vec));
|
||||
|
||||
// assign with same size
|
||||
vec = {0.25,0.5,0.25};
|
||||
v.SetDoubleArray(vec);
|
||||
ASSERT_EQ(ToNT(v).type, NT_DOUBLE_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.size, 3u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[0], vec[0]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[1], vec[1]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[2], vec[2]);
|
||||
ASSERT_EQ(v.type(), NT_DOUBLE_ARRAY);
|
||||
ASSERT_EQ(v.GetDoubleArray(), llvm::ArrayRef<double>(vec));
|
||||
|
||||
// assign with different size
|
||||
vec = {0.5,0.25};
|
||||
v.SetDoubleArray(vec);
|
||||
ASSERT_EQ(ToNT(v).type, NT_DOUBLE_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.size, 2u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[0], vec[0]);
|
||||
ASSERT_EQ(ToNT(v).data.arr_double.arr[1], vec[1]);
|
||||
ASSERT_EQ(v.type(), NT_DOUBLE_ARRAY);
|
||||
ASSERT_EQ(v.GetDoubleArray(), llvm::ArrayRef<double>(vec));
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, StringArray) {
|
||||
Value v;
|
||||
std::vector<StringValue> vec;
|
||||
vec.push_back(StringValue("hello"));
|
||||
vec.push_back(StringValue("goodbye"));
|
||||
vec.push_back(StringValue("string"));
|
||||
v.SetStringArray(vec);
|
||||
ASSERT_TRUE(vec.empty());
|
||||
ASSERT_EQ(ToNT(v).type, NT_STRING_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.size, 3u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[0].str, llvm::StringRef("hello"));
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[1].str, llvm::StringRef("goodbye"));
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[2].str, llvm::StringRef("string"));
|
||||
ASSERT_EQ(v.type(), NT_STRING_ARRAY);
|
||||
ASSERT_EQ(v.GetStringArray()[0], llvm::StringRef("hello"));
|
||||
ASSERT_EQ(v.GetStringArray()[1], llvm::StringRef("goodbye"));
|
||||
ASSERT_EQ(v.GetStringArray()[2], llvm::StringRef("string"));
|
||||
|
||||
// assign with same size
|
||||
vec.clear();
|
||||
vec.push_back(StringValue("s1"));
|
||||
vec.push_back(StringValue("str2"));
|
||||
vec.push_back(StringValue("string3"));
|
||||
v.SetStringArray(vec);
|
||||
ASSERT_TRUE(vec.empty());
|
||||
ASSERT_EQ(ToNT(v).type, NT_STRING_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.size, 3u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[0].str, llvm::StringRef("s1"));
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[1].str, llvm::StringRef("str2"));
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[2].str, llvm::StringRef("string3"));
|
||||
ASSERT_EQ(v.type(), NT_STRING_ARRAY);
|
||||
ASSERT_EQ(v.GetStringArray()[0], llvm::StringRef("s1"));
|
||||
ASSERT_EQ(v.GetStringArray()[1], llvm::StringRef("str2"));
|
||||
ASSERT_EQ(v.GetStringArray()[2], llvm::StringRef("string3"));
|
||||
|
||||
// assign with different size
|
||||
vec.clear();
|
||||
vec.push_back(StringValue("short"));
|
||||
vec.push_back(StringValue("er"));
|
||||
v.SetStringArray(vec);
|
||||
ASSERT_TRUE(vec.empty());
|
||||
ASSERT_EQ(ToNT(v).type, NT_STRING_ARRAY);
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.size, 2u);
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[0].str, llvm::StringRef("short"));
|
||||
ASSERT_EQ(ToNT(v).data.arr_string.arr[1].str, llvm::StringRef("er"));
|
||||
ASSERT_EQ(v.type(), NT_STRING_ARRAY);
|
||||
ASSERT_EQ(v.GetStringArray()[0], llvm::StringRef("short"));
|
||||
ASSERT_EQ(v.GetStringArray()[1], llvm::StringRef("er"));
|
||||
}
|
||||
|
||||
TEST_F(ValueDeathTest, GetAssertions) {
|
||||
Value v;
|
||||
ASSERT_DEATH(v.GetBoolean(), "NT_Value::type == NT_BOOLEAN");
|
||||
ASSERT_DEATH(v.GetDouble(), "NT_Value::type == NT_DOUBLE");
|
||||
ASSERT_DEATH(v.GetString(), "NT_Value::type == NT_STRING");
|
||||
ASSERT_DEATH(v.GetRaw(), "NT_Value::type == NT_RAW");
|
||||
ASSERT_DEATH(v.GetBooleanArray(), "NT_Value::type == NT_BOOLEAN_ARRAY");
|
||||
ASSERT_DEATH(v.GetDoubleArray(), "NT_Value::type == NT_DOUBLE_ARRAY");
|
||||
ASSERT_DEATH(v.GetStringArray(), "NT_Value::type == NT_STRING_ARRAY");
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, UnassignedComparison) {
|
||||
Value v1, v2;
|
||||
ASSERT_EQ(v1, v2);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, MixedComparison) {
|
||||
Value v1, v2;
|
||||
v1.SetBoolean(true);
|
||||
ASSERT_NE(v1, v2); // unassigned vs boolean
|
||||
v2.SetDouble(0.5);
|
||||
ASSERT_NE(v1, v2); // boolean vs double
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, BooleanComparison) {
|
||||
Value v1, v2;
|
||||
v1.SetBoolean(true);
|
||||
v2.SetBoolean(true);
|
||||
ASSERT_EQ(v1, v2);
|
||||
v2.SetBoolean(false);
|
||||
ASSERT_NE(v1, v2);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, DoubleComparison) {
|
||||
Value v1, v2;
|
||||
v1.SetDouble(0.25);
|
||||
v2.SetDouble(0.25);
|
||||
ASSERT_EQ(v1, v2);
|
||||
v2.SetDouble(0.5);
|
||||
ASSERT_NE(v1, v2);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, StringComparison) {
|
||||
Value v1, v2;
|
||||
v1.SetString("hello");
|
||||
v2.SetString("hello");
|
||||
ASSERT_EQ(v1, v2);
|
||||
v2.SetString("world"); // different contents
|
||||
ASSERT_NE(v1, v2);
|
||||
v2.SetString("goodbye"); // different size
|
||||
ASSERT_NE(v1, v2);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, BooleanArrayComparison) {
|
||||
Value v1, v2;
|
||||
std::vector<int> vec{1,0,1};
|
||||
v1.SetBooleanArray(vec);
|
||||
v2.SetBooleanArray(vec);
|
||||
ASSERT_EQ(v1, v2);
|
||||
|
||||
// different contents
|
||||
vec = {1,1,1};
|
||||
v2.SetBooleanArray(vec);
|
||||
ASSERT_NE(v1, v2);
|
||||
|
||||
// different size
|
||||
vec = {1,0};
|
||||
v2.SetBooleanArray(vec);
|
||||
ASSERT_NE(v1, v2);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, DoubleArrayComparison) {
|
||||
Value v1, v2;
|
||||
std::vector<double> vec{0.5,0.25,0.5};
|
||||
v1.SetDoubleArray(vec);
|
||||
v2.SetDoubleArray(vec);
|
||||
ASSERT_EQ(v1, v2);
|
||||
|
||||
// different contents
|
||||
vec = {0.5,0.5,0.5};
|
||||
v2.SetDoubleArray(vec);
|
||||
ASSERT_NE(v1, v2);
|
||||
|
||||
// different size
|
||||
vec = {0.5,0.25};
|
||||
v2.SetDoubleArray(vec);
|
||||
ASSERT_NE(v1, v2);
|
||||
}
|
||||
|
||||
TEST_F(ValueTest, StringArrayComparison) {
|
||||
Value v1, v2;
|
||||
std::vector<StringValue> vec;
|
||||
vec.push_back(StringValue("hello"));
|
||||
vec.push_back(StringValue("goodbye"));
|
||||
vec.push_back(StringValue("string"));
|
||||
v1.SetStringArray(vec);
|
||||
vec.clear();
|
||||
vec.push_back(StringValue("hello"));
|
||||
vec.push_back(StringValue("goodbye"));
|
||||
vec.push_back(StringValue("string"));
|
||||
v2.SetStringArray(vec);
|
||||
ASSERT_EQ(v1, v2);
|
||||
|
||||
// different contents
|
||||
vec.clear();
|
||||
vec.push_back(StringValue("hello"));
|
||||
vec.push_back(StringValue("goodby2"));
|
||||
vec.push_back(StringValue("string"));
|
||||
v2.SetStringArray(vec);
|
||||
ASSERT_NE(v1, v2);
|
||||
|
||||
// different sized contents
|
||||
vec.clear();
|
||||
vec.push_back(StringValue("hello"));
|
||||
vec.push_back(StringValue("goodbye2"));
|
||||
vec.push_back(StringValue("string"));
|
||||
v2.SetStringArray(vec);
|
||||
ASSERT_NE(v1, v2);
|
||||
|
||||
// different size
|
||||
vec.clear();
|
||||
vec.push_back(StringValue("hello"));
|
||||
vec.push_back(StringValue("goodbye"));
|
||||
v2.SetStringArray(vec);
|
||||
ASSERT_NE(v1, v2);
|
||||
}
|
||||
|
||||
} // namespace ntimpl
|
||||
Reference in New Issue
Block a user