Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gtest uint testing added in basic format #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ build/*
doc/*
workspace.code-workspace
sdkconfig
googletest
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "googletest"]
path = googletest
url = https://github.com/google/googletest.git
61 changes: 48 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,57 @@ cmake_minimum_required(VERSION 3.22)

set(CMAKE_CXX_STANDARD 17)

set(EXTRA_COMPONENT_DIRS src)
if(${GTEST})
#Creates a variable named TEST_FILES that can be used via ${TEST_FILES}
set(TEST_FILES
src/test/testClass_test.cpp
)
#Libraries that are needed by the test files
set(TEST_LIBS
testClass_lib
)

set(application_name "esp32_lora_gateway")
set(application_version "0.1.0")
#adds include directories before adding subdirectories so they have access to the header prototypes
include_directories(components/testClass)

set(PROJECT_VER ${application_version})
#tells cmake that there is another CMakeList.txt in components/testClass that it needs to process
add_subdirectory(src/test)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(unit-tests)

# idf.py -DCMAKE_BUILD_TYPE=Debug reconfigure
# idf.py -DCMAKE_BUILD_TYPE=Release reconfigure
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(opt_level -O0)
add_definitions(-DDEBUG_BUILD)
message("running GTEST")
add_subdirectory(googletest)

# adds to the include path
# We have access to the var gtest_SOURCE_DIR because it is being set in the `lib` CMake files that is called above
# via add_subdirectory(google)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
include_directories(${gmock_SOURCE_DIR}/include ${gmock_SOURCE_DIR})

# Creates an executable called Google_Test_run and adds tests from testClass/test/test.cpp
add_executable(Google_Tests_run ${TEST_FILES})

# link the project libraries and google test library to the executable Google_Tests_run
target_link_libraries(Google_Tests_run ${TEST_LIBS} gtest gmock gtest_main)
else()
set(opt_level -Os)
endif()
set(EXTRA_COMPONENT_DIRS src)

set(application_name "esp32_lora_gateway")
set(application_version "0.1.0")

set(PROJECT_VER ${application_version})

include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# idf.py -DCMAKE_BUILD_TYPE=Debug reconfigure
# idf.py -DCMAKE_BUILD_TYPE=Release reconfigure
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(opt_level -O0)
add_definitions(-DDEBUG_BUILD)
else()
set(opt_level -Os)
endif()

project(${application_name})

project(${application_name})
endif()
2 changes: 1 addition & 1 deletion code-format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ astyle \
--unpad-paren \
--suffix=none \
"$@" \
--recursive "src/core/*.c" "src/core/*.h" "src/app/*.c" "src/app/*.h"
--recursive "src/core/*.c" "src/core/*.h" "src/app/*.c" "src/app/*.h" "src/test/*.cpp" "src/test/*.h"
1 change: 1 addition & 0 deletions googletest
Submodule googletest added at 2d4f20
23 changes: 23 additions & 0 deletions src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
if(${GTEST})
project(testClass)

#Creates an env var for building HEADER_FILES
set(HEADER_FILES
testClass.h
)
#Creates an env var for building SOURCE_FILES
set(SOURCE_FILES
testClass.cpp
)

#Adds a library called testClass_lib to be built from the SOURCE_FILES, will be statically linked
add_library(testClass_lib STATIC ${SOURCE_FILES} ${HEADER_FILES})
else()
set(SOURCE_FILES
testClass.cpp
)

set(COMPONENT_SRCS "${SOURCE_FILES}")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component()
endif()
27 changes: 27 additions & 0 deletions src/test/testClass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "testClass.h"

#include <string.h>

// Clones a 0-terminated C string, allocating memory using new.
const char *MyString::CloneCString(const char *a_c_string)
{
if (a_c_string == nullptr) {
return nullptr;
}

const size_t len = strlen(a_c_string);
char *const clone = new char[len + 1];
memcpy(clone, a_c_string, len + 1);

return clone;
}

// Sets the 0-terminated C string this MyString object
// represents.
void MyString::Set(const char *a_c_string)
{
// Makes sure this works when c_string == c_string_
const char *const temp = MyString::CloneCString(a_c_string);
delete[] c_string_;
c_string_ = temp;
}
61 changes: 61 additions & 0 deletions src/test/testClass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef TEST_CLASS_H
#define TEST_CLASS_H


#include <string.h>

// A simple string class.
class MyString {
private:
const char *c_string_;
const MyString &operator=(const MyString &rhs);

public:
// Clones a 0-terminated C string, allocating memory using new.
static const char *CloneCString(const char *a_c_string);

////////////////////////////////////////////////////////////
//
// C'tors

// The default c'tor constructs a NULL string.
MyString() : c_string_(nullptr) {}

// Constructs a MyString by cloning a 0-terminated C string.
explicit MyString(const char *a_c_string) : c_string_(nullptr)
{
Set(a_c_string);
}

// Copy c'tor
MyString(const MyString &string) : c_string_(nullptr)
{
Set(string.c_string_);
}

////////////////////////////////////////////////////////////
//
// D'tor. MyString is intended to be a final class, so the d'tor
// doesn't need to be virtual.
~MyString()
{
delete[] c_string_;
}

// Gets the 0-terminated C string this MyString object represents.
const char *c_string() const
{
return c_string_;
}

size_t Length() const
{
return c_string_ == nullptr ? 0 : strlen(c_string_);
}

// Sets the 0-terminated C string this MyString object represents.
void Set(const char *c_string);
};


#endif //TEST_CLASS_H
71 changes: 71 additions & 0 deletions src/test/testClass_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "testClass.h"
#include "gtest/gtest.h"
namespace {
// In this example, we test the MyString class (a simple string).

// Tests the default c'tor.
TEST(MyString, DefaultConstructor)
{
const MyString s;

// Asserts that s.c_string() returns NULL.
//
// <TechnicalDetails>
//
// If we write NULL instead of
//
// static_cast<const char *>(NULL)
//
// in this assertion, it will generate a warning on gcc 3.4. The
// reason is that EXPECT_EQ needs to know the types of its
// arguments in order to print them when it fails. Since NULL is
// #defined as 0, the compiler will use the formatter function for
// int to print it. However, gcc thinks that NULL should be used as
// a pointer, not an int, and therefore complains.
//
// The root of the problem is C++'s lack of distinction between the
// integer number 0 and the null pointer constant. Unfortunately,
// we have to live with this fact.
//
// </TechnicalDetails>
EXPECT_STREQ(nullptr, s.c_string());

EXPECT_EQ(0u, s.Length());
}

const char kHelloString[] = "Hello, world!";

// Tests the c'tor that accepts a C string.
TEST(MyString, ConstructorFromCString)
{
const MyString s(kHelloString);
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
EXPECT_EQ(sizeof(kHelloString) / sizeof(kHelloString[0]) - 1, s.Length());
}

// Tests the copy c'tor.
TEST(MyString, CopyConstructor)
{
const MyString s1(kHelloString);
const MyString s2 = s1;
EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString));
}

// Tests the Set method.
TEST(MyString, Set)
{
MyString s;

s.Set(kHelloString);
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));

// Set should work when the input pointer is the same as the one
// already in the MyString object.
s.Set(s.c_string());
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));

// Can we set the MyString to NULL?
s.Set(nullptr);
EXPECT_STREQ(nullptr, s.c_string());
}
} // namespace