Setup tests via Catch2

This commit is contained in:
Sameer Rahmani 2021-04-06 00:21:43 +01:00
parent f73cfe7aaf
commit 0020f95a80
6 changed files with 88 additions and 22 deletions

View File

@ -46,12 +46,8 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
option(ENABLE_LOG "Enable logging" OFF)
option(ENABLE_EXPR_LOG "Enable AExpr 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(FetchContent)
@ -107,7 +103,8 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/)
# Testing only available if this is the main app
# 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)
endif()

17
builder
View File

@ -64,9 +64,14 @@ function memcheck() {
popd_build
}
function run-tests() {
$BUILD_DIR/tests/tests
}
function tests() {
pushed_build
ctest
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON $ROOT_DIR
ninja -j `nproc`
popd_build
}
@ -102,6 +107,10 @@ case "$command" in
"compile")
compile
;;
"compile-and-test")
compile
run-tests
;;
"run")
run "${@:2}"
;;
@ -117,8 +126,11 @@ case "$command" in
"memcheck")
memcheck
;;
"memcheck")
"tests")
clean
mkdir -p $BUILD_DIR
tests
run-tests
;;
"clean")
rm -rf $BUILD_DIR
@ -128,6 +140,7 @@ case "$command" in
mkdir -p $BUILD_DIR
build
tests
run-tests
memcheck
;;
*)

View File

@ -33,6 +33,12 @@ namespace serene {
/// the syntax directly. Like function definitions.
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.
/// Each expression has to define the interface of the `ExpressionConcept`
/// class as generic functions. **REMEMBER TO NOT INHERIT FROM THESE CLASSES**
@ -40,20 +46,32 @@ class Expression {
public:
template <typename T>
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:
/// The generic interface which each type of expression has to implement
/// in order to act like an `Expression`
struct ExpressionConcept {
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
/// dispatcher on type.
template <typename T> struct ExpressionImpl : ExpressionConcept {
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;
};

40
src/exprs/expression.cpp Normal file
View File

@ -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

View File

@ -1,16 +1,10 @@
# Testing library
FetchContent_Declare(
catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.9.1
)
FetchContent_MakeAvailable(catch2)
# Catch2 should be installed system wide
find_package(Catch2 REQUIRED)
# Tests need to be added as executables first
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
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.
# You can also run examples and check the output, as well.
# add_test(NAME testlibtest serene testlib) # Command can be a target
include(CTest)
include(Catch)
catch_discover_tests(tests)

View File

@ -1,3 +1,4 @@
int main() {
return 0;
}
#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"
TEST_CASE("Test stuff", "[abc]") { REQUIRE(1 == 2); }