I have this project for university which we have to make a small game in C++. I'm trying to use Test Driven Development for the most fundamental parts of the game so I was trying to set up Catch2, I already set up CMake and it works just fine, then I set up Catch2 v3 but it isn't working properly
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(game VERSION 0.1)
file(GLOB_RECURSE SRC_FILES src/*.cpp)
add_executable(game main.cpp ${SRC_FILES})
target_include_directories(game PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include())
find_package(Catch2 3 REQUIRED)
# These tests can use the Catch2-provided main
add_executable(tests ../testing/test.cpp)
target_include_directories(tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include())
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
The following is my test.cpp file (with only one of the test cases so this post doesn't get huge):
/* Include the unit testing libraries */
#define CATCH_CONFIG_MAIN
#include <catch2/catch_test_macros.hpp>
/* Include the code that we plan to test */
#include "worldmap.h"
/** of course we could check every single possible value, but this isn't
* going to be an option in most cases as we might have to check
* billions of possible values which isn't realistic **/
TEST_CASE( "1: Children (worldmap.h)", "[multi-file:1]" )
{
const std::string expectedAnswer = "child";
const int minimum = 5;
const int maximum = 12;
WHEN( "Is a child, 5 to 12 years")
{
for( int test=minimum; test<=maximum; ++test )
{
INFO( "Age is " << test );
REQUIRE( ageDesc(test) == expectedAnswer );
}
}
WHEN( "Is not a child edge cases" )
{
// making sure that just outside the min and max of the range is correct
INFO( "Age is " << minimum-1 );
REQUIRE( ageDesc(minimum-1) != expectedAnswer );
INFO( "Age is " << maximum+1 );
REQUIRE( ageDesc(maximum+1) != expectedAnswer );
}
}
worldmap.cpp:
#include <string>
#include "worldmap.h"
std::string ageDesc( int age )
{
if( age < 0 || age > 122) return "lying";
if( age < 5 ) return "baby";
if( age >= 5 && age <= 12 ) return "child";
if( age >= 13 && age <= 19 ) return "teenager";
if( age >= 65 && age <= 122 ) return "oap";
return "adult";
}
worldmap.h:
#ifndef WORLDMAP_H
#define WORLDMAP_H
std::string ageDesc( int age );
#endif
main.cpp:
#include <iostream>
#include "worldmap.h"
int main() {
std::cout << "\nHow old are you? ";
int age;
std::cin >> age;
std::cout<<ageDesc(age)<<std::endl;
return 0;
}
My file structure is as follows:
-- main.cpp
- src -- worldmap.cpp
- include -- worldmap.h
- testing -- test.cpp
- build -- all cmake files
My main.cpp, worldmap.cpp and worldmap.h are correctly "linked" and they work just fine I've tested them before and when using cmake i was able to compile everything correctly and even run the game (by the way the age thing is just the code provided by my university when showing testing files, I couldn't come up with a better test at the moment so I just used theirs, essentially it just asks the user what their age is and returns whether they're a baby, child, teen, adult, OAP, etc...) The problem is that my test file gives me the error:
undefined reference to 'ageDesc[abi:cxx11](int)'
but it is defined in worldmap.h which is being included in the test file.
I have googled and looked at the documentation but haven't found anything about this.
The only proper answer on google mentioned how the #define CATCH_CONFIG_MAIN
should come before #include <catch2.hpp>
but that was for v3, so I'm using #include <catch2/catch_test_macros.hpp>
and I've tried to both use and remove the CATCH_CONFIG_MAIN definition and it still gives me the same error.