Setup tests via Catch2
This commit is contained in:
parent
f73cfe7aaf
commit
0020f95a80
|
@ -46,12 +46,8 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||||
option(ENABLE_LOG "Enable logging" OFF)
|
option(ENABLE_LOG "Enable logging" OFF)
|
||||||
option(ENABLE_EXPR_LOG "Enable AExpr logging" OFF)
|
option(ENABLE_EXPR_LOG "Enable AExpr logging" OFF)
|
||||||
option(ENABLE_READER_LOG "Enable reader logging" OFF)
|
option(ENABLE_READER_LOG "Enable reader logging" OFF)
|
||||||
|
option(BUILD_TESTING "Enable tests" OFF)
|
||||||
|
|
||||||
# Testing only available if this is the main app
|
|
||||||
# Note this needs to be done in the main CMakeLists
|
|
||||||
# since it calls enable_testing, which must be in the
|
|
||||||
# main CMakeLists.
|
|
||||||
include(CTest)
|
|
||||||
|
|
||||||
include(cotire)
|
include(cotire)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
@ -107,7 +103,8 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/)
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||||
# Testing only available if this is the main app
|
# Testing only available if this is the main app
|
||||||
# Emergency override SERENE_CMAKE_BUILD_TESTING provided as well
|
# Emergency override SERENE_CMAKE_BUILD_TESTING provided as well
|
||||||
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SERENE_CMAKE_BUILD_TESTING) AND BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
|
message("Build the test binary")
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
17
builder
17
builder
|
@ -64,9 +64,14 @@ function memcheck() {
|
||||||
popd_build
|
popd_build
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function run-tests() {
|
||||||
|
$BUILD_DIR/tests/tests
|
||||||
|
}
|
||||||
|
|
||||||
function tests() {
|
function tests() {
|
||||||
pushed_build
|
pushed_build
|
||||||
ctest
|
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON $ROOT_DIR
|
||||||
|
ninja -j `nproc`
|
||||||
popd_build
|
popd_build
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +107,10 @@ case "$command" in
|
||||||
"compile")
|
"compile")
|
||||||
compile
|
compile
|
||||||
;;
|
;;
|
||||||
|
"compile-and-test")
|
||||||
|
compile
|
||||||
|
run-tests
|
||||||
|
;;
|
||||||
"run")
|
"run")
|
||||||
run "${@:2}"
|
run "${@:2}"
|
||||||
;;
|
;;
|
||||||
|
@ -117,8 +126,11 @@ case "$command" in
|
||||||
"memcheck")
|
"memcheck")
|
||||||
memcheck
|
memcheck
|
||||||
;;
|
;;
|
||||||
"memcheck")
|
"tests")
|
||||||
|
clean
|
||||||
|
mkdir -p $BUILD_DIR
|
||||||
tests
|
tests
|
||||||
|
run-tests
|
||||||
;;
|
;;
|
||||||
"clean")
|
"clean")
|
||||||
rm -rf $BUILD_DIR
|
rm -rf $BUILD_DIR
|
||||||
|
@ -128,6 +140,7 @@ case "$command" in
|
||||||
mkdir -p $BUILD_DIR
|
mkdir -p $BUILD_DIR
|
||||||
build
|
build
|
||||||
tests
|
tests
|
||||||
|
run-tests
|
||||||
memcheck
|
memcheck
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|
|
@ -33,6 +33,12 @@ namespace serene {
|
||||||
/// the syntax directly. Like function definitions.
|
/// the syntax directly. Like function definitions.
|
||||||
namespace exprs {
|
namespace exprs {
|
||||||
|
|
||||||
|
/// This enum represent the expression type and **not** the value type.
|
||||||
|
enum class ExprType {
|
||||||
|
Symbol,
|
||||||
|
List,
|
||||||
|
};
|
||||||
|
|
||||||
/// The polymorphic type that works as the entry point to the exprs system.
|
/// The polymorphic type that works as the entry point to the exprs system.
|
||||||
/// Each expression has to define the interface of the `ExpressionConcept`
|
/// Each expression has to define the interface of the `ExpressionConcept`
|
||||||
/// class as generic functions. **REMEMBER TO NOT INHERIT FROM THESE CLASSES**
|
/// class as generic functions. **REMEMBER TO NOT INHERIT FROM THESE CLASSES**
|
||||||
|
@ -40,20 +46,32 @@ class Expression {
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Expression(T e) : self(new ExpressionImpl<T>(std::move(e))){};
|
Expression(T e) : self(new ExpressionImpl<T>(std::move(e))){};
|
||||||
|
Expression(const Expression &e) : self(e.self->copy()){}; // Copy ctor
|
||||||
|
Expression(Expression &&e) noexcept = default; // Move ctor
|
||||||
|
|
||||||
|
Expression &operator=(const Expression &e);
|
||||||
|
Expression &operator=(Expression &&e) noexcept = default;
|
||||||
|
|
||||||
|
ExprType getType();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The generic interface which each type of expression has to implement
|
/// The generic interface which each type of expression has to implement
|
||||||
/// in order to act like an `Expression`
|
/// in order to act like an `Expression`
|
||||||
struct ExpressionConcept {
|
struct ExpressionConcept {
|
||||||
virtual ~ExpressionConcept() = default;
|
virtual ~ExpressionConcept() = default;
|
||||||
virtual ExpressionConcept *copy_() const = 0;
|
virtual ExpressionConcept *copy() const = 0;
|
||||||
|
|
||||||
|
virtual ExprType getType();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The generic implementation of `ExpressionConcept` which acts as the
|
/// The generic implementation of `ExpressionConcept` which acts as the
|
||||||
/// dispatcher on type.
|
/// dispatcher on type.
|
||||||
template <typename T> struct ExpressionImpl : ExpressionConcept {
|
template <typename T> struct ExpressionImpl : ExpressionConcept {
|
||||||
ExpressionImpl(T e) : expr(std::move(e)){};
|
ExpressionImpl(T e) : expr(std::move(e)){};
|
||||||
ExpressionConcept *copy_() const { return new ExpressionImpl(*this); }
|
ExpressionConcept *copy() const { return new ExpressionImpl(*this); }
|
||||||
|
|
||||||
|
/// In order to make llvm's RTTI to work we need this method.
|
||||||
|
ExprType getType() { return expr.getType(); }
|
||||||
|
|
||||||
T expr;
|
T expr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* -*- C++ -*-
|
||||||
|
* Serene programming language.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "serene/exprs/expression.h"
|
||||||
|
|
||||||
|
namespace serene {
|
||||||
|
namespace exprs {
|
||||||
|
|
||||||
|
/// Move \p `e` and replace the current object with it
|
||||||
|
Expression &Expression::operator=(const Expression &e) {
|
||||||
|
Expression tmp(e);
|
||||||
|
*this = std::move(tmp);
|
||||||
|
return *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
ExprType Expression::getType() { return self->getType(); }
|
||||||
|
|
||||||
|
} // namespace exprs
|
||||||
|
} // namespace serene
|
|
@ -1,16 +1,10 @@
|
||||||
# Testing library
|
# Catch2 should be installed system wide
|
||||||
FetchContent_Declare(
|
find_package(Catch2 REQUIRED)
|
||||||
catch2
|
|
||||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
|
||||||
GIT_TAG v2.9.1
|
|
||||||
)
|
|
||||||
|
|
||||||
FetchContent_MakeAvailable(catch2)
|
|
||||||
|
|
||||||
# Tests need to be added as executables first
|
# Tests need to be added as executables first
|
||||||
add_executable(tests serenetests.cpp)
|
add_executable(tests serenetests.cpp)
|
||||||
|
|
||||||
target_compile_features(tests PRIVATE cxx_std_20)
|
target_compile_features(tests PRIVATE cxx_std_14)
|
||||||
|
|
||||||
# Should be linked to the main library, as well as the Catch2 testing library
|
# Should be linked to the main library, as well as the Catch2 testing library
|
||||||
target_link_libraries(tests PRIVATE serene Catch2::Catch2)
|
target_link_libraries(tests PRIVATE serene Catch2::Catch2)
|
||||||
|
@ -18,3 +12,6 @@ target_link_libraries(tests PRIVATE serene Catch2::Catch2)
|
||||||
# If you register a test, then ctest and make test will run it.
|
# If you register a test, then ctest and make test will run it.
|
||||||
# You can also run examples and check the output, as well.
|
# You can also run examples and check the output, as well.
|
||||||
# add_test(NAME testlibtest serene testlib) # Command can be a target
|
# add_test(NAME testlibtest serene testlib) # Command can be a target
|
||||||
|
include(CTest)
|
||||||
|
include(Catch)
|
||||||
|
catch_discover_tests(tests)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
int main() {
|
#define CATCH_CONFIG_MAIN
|
||||||
return 0;
|
#include "catch2/catch.hpp"
|
||||||
}
|
|
||||||
|
TEST_CASE("Test stuff", "[abc]") { REQUIRE(1 == 2); }
|
||||||
|
|
Loading…
Reference in New Issue