Initial unit tests
This commit is contained in:
parent
326decd3de
commit
6e27e99735
@ -15,7 +15,10 @@ if (NOT LLVM_ENABLE_RTTI)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_executable(op-finder-tests
|
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
|
target_link_libraries(op-finder-tests
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
|||||||
@ -51,3 +51,45 @@ TEST_CASE("Find unary operations", "[basic_operation]")
|
|||||||
REQUIRE(op->type_rhs.empty());
|
REQUIRE(op->type_rhs.empty());
|
||||||
REQUIRE(op->type_result == "int");
|
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)
|
, 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(),
|
clang::tooling::newFrontendActionFactory(&action)->create(),
|
||||||
code,
|
code,
|
||||||
RunOnCodeFixture::INPUT_FILE
|
RunOnCodeFixture::INPUT_FILE
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<OperationLog>& RunOnCodeFixture::operator()(const std::string& code)
|
||||||
|
{
|
||||||
|
const bool success = runCode(code);
|
||||||
|
|
||||||
REQUIRE(success);
|
REQUIRE(success);
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,8 @@ struct RunOnCodeFixture
|
|||||||
|
|
||||||
RunOnCodeFixture();
|
RunOnCodeFixture();
|
||||||
|
|
||||||
|
bool runCode(const std::string& code);
|
||||||
|
|
||||||
const std::vector<OperationLog>& operator()(const std::string& code);
|
const std::vector<OperationLog>& operator()(const std::string& code);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user