Initial unit tests
This commit is contained in:
parent
326decd3de
commit
6e27e99735
@ -15,7 +15,10 @@ if (NOT LLVM_ENABLE_RTTI)
|
||||
endif ()
|
||||
|
||||
add_executable(op-finder-tests
|
||||
main.cpp basic_operations.cpp fixtures/RunOnCodeFixture.cpp fixtures/RunOnCodeFixture.hpp)
|
||||
main.cpp
|
||||
fixtures/RunOnCodeFixture.cpp
|
||||
basic_operations.cpp
|
||||
branches.cpp)
|
||||
|
||||
target_link_libraries(op-finder-tests
|
||||
PUBLIC
|
||||
|
||||
@ -51,3 +51,45 @@ TEST_CASE("Find unary operations", "[basic_operation]")
|
||||
REQUIRE(op->type_rhs.empty());
|
||||
REQUIRE(op->type_result == "int");
|
||||
}
|
||||
|
||||
TEST_CASE("Find subscript operation", "[basic_operation]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a[4]; (void)a[4]; }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 1);
|
||||
|
||||
const OperationLog& log = operations.front();
|
||||
|
||||
REQUIRE(log.entry_type == OperationLog::BasicOperation::TYPE_NAME);
|
||||
|
||||
const OperationLog::BasicOperation* op = (OperationLog::BasicOperation*)(log.entry.get());
|
||||
|
||||
REQUIRE(op->operation_name == "subscript");
|
||||
REQUIRE(op->type_lhs == "int *");
|
||||
REQUIRE(op->type_rhs == "int");
|
||||
REQUIRE(op->type_result == "int");
|
||||
}
|
||||
|
||||
TEST_CASE("Find subscript operation reversed", "[basic_operation]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a[4]; (void)4[a]; }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 1);
|
||||
|
||||
const OperationLog& log = operations.front();
|
||||
|
||||
REQUIRE(log.entry_type == OperationLog::BasicOperation::TYPE_NAME);
|
||||
|
||||
const OperationLog::BasicOperation* op = (OperationLog::BasicOperation*)(log.entry.get());
|
||||
|
||||
REQUIRE(op->operation_name == "subscript");
|
||||
REQUIRE(op->type_lhs == "int *");
|
||||
REQUIRE(op->type_rhs == "int");
|
||||
REQUIRE(op->type_result == "int");
|
||||
}
|
||||
|
||||
125
op-finder-tests/branches.cpp
Normal file
125
op-finder-tests/branches.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// Created by erki on 07.03.21.
|
||||
//
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include "fixtures/RunOnCodeFixture.hpp"
|
||||
|
||||
TEST_CASE("For loop without header", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (;;) {} }";
|
||||
REQUIRE(fixture.runCode(code));
|
||||
|
||||
REQUIRE(fixture.storage.getOperations().empty());
|
||||
}
|
||||
|
||||
TEST_CASE("For loop with init only.", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (a = 4;;) {} }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 1);
|
||||
|
||||
const OperationLog& log = operations.front();
|
||||
|
||||
REQUIRE(log.branch_number == 1);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("For loop with init & cond.", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (a = 4; a < 4;) {} }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 2);
|
||||
|
||||
const OperationLog& log_init = operations.at(0);
|
||||
REQUIRE(log_init.branch_number == 1);
|
||||
|
||||
const OperationLog& log_cond = operations.at(1);
|
||||
REQUIRE(log_cond.branch_number == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("For loop with init & inc.", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (a = 4;;a++) {} }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 2);
|
||||
|
||||
const OperationLog& log_init = operations.at(0);
|
||||
REQUIRE(log_init.branch_number == 1);
|
||||
|
||||
const OperationLog& log_inc = operations.at(1);
|
||||
REQUIRE(log_inc.branch_number == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("For loop with full header.", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (a = 4; a < 4 ;a++) {} }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 3);
|
||||
|
||||
const OperationLog& log_init = operations.at(0);
|
||||
REQUIRE(log_init.branch_number == 1);
|
||||
|
||||
const OperationLog& log_cond = operations.at(1);
|
||||
REQUIRE(log_cond.branch_number == 2);
|
||||
|
||||
const OperationLog& log_inc = operations.at(2);
|
||||
REQUIRE(log_inc.branch_number == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("For loop without init.", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (;a < 4 ;a++) {} }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 2);
|
||||
|
||||
const OperationLog& log_cond = operations.at(0);
|
||||
REQUIRE(log_cond.branch_number == 0);
|
||||
|
||||
const OperationLog& log_inc = operations.at(1);
|
||||
REQUIRE(log_inc.branch_number == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("For loop closes branches inside the loop.", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (a = 4; a < 4 ; a++) { a = 5; } }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 4);
|
||||
|
||||
const OperationLog& log_inner = operations.back();
|
||||
REQUIRE(log_inner.branch_number == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("For loop closes branches outside the loop.", "[branches][for_loops]")
|
||||
{
|
||||
RunOnCodeFixture fixture;
|
||||
|
||||
const std::string code = "int main() { int a; for (a = 4; a < 4 ; a++) {} a = 5; }";
|
||||
const auto& operations = fixture(code);
|
||||
|
||||
REQUIRE(operations.size() == 4);
|
||||
|
||||
const OperationLog& log_outer = operations.back();
|
||||
REQUIRE(log_outer.branch_number == 0);
|
||||
}
|
||||
@ -14,13 +14,18 @@ RunOnCodeFixture::RunOnCodeFixture()
|
||||
, action(&finder)
|
||||
{ }
|
||||
|
||||
const std::vector<OperationLog>& RunOnCodeFixture::operator()(const std::string& code)
|
||||
bool RunOnCodeFixture::runCode(const std::string& code)
|
||||
{
|
||||
const bool success = clang::tooling::runToolOnCode(
|
||||
return clang::tooling::runToolOnCode(
|
||||
clang::tooling::newFrontendActionFactory(&action)->create(),
|
||||
code,
|
||||
RunOnCodeFixture::INPUT_FILE
|
||||
);
|
||||
}
|
||||
|
||||
const std::vector<OperationLog>& RunOnCodeFixture::operator()(const std::string& code)
|
||||
{
|
||||
const bool success = runCode(code);
|
||||
|
||||
REQUIRE(success);
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@ struct RunOnCodeFixture
|
||||
|
||||
RunOnCodeFixture();
|
||||
|
||||
bool runCode(const std::string& code);
|
||||
|
||||
const std::vector<OperationLog>& operator()(const std::string& code);
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user