snake/tests/Interpreter.cpp

336 lines
8.2 KiB
C++
Raw Normal View History

#include <catch2/catch.hpp>
#include "../src/Interpreter.hpp"
#define TEST_RUN(SRC, ...) \
test_run(SRC, {__VA_ARGS__})
using namespace sn;
struct StateMock: public State {
std::vector<std::filesystem::path> modified_files;
2023-10-14 15:55:51 +00:00
explicit StateMock(std::vector<std::filesystem::path> const& p_modified_files)
: modified_files { p_modified_files }
{
}
virtual void init(std::vector<std::filesystem::path> const&) override
{
}
virtual void update(std::filesystem::path) override
{
}
virtual std::vector<std::filesystem::path>
get_modified_files(std::vector<std::filesystem::path> const&) override
{
return modified_files;
}
};
struct LoaderMock: public Loader {
std::string snakefile;
2023-10-14 15:55:51 +00:00
explicit LoaderMock(std::string const& p_snakefile)
: snakefile { p_snakefile }
{
}
virtual std::filesystem::path find_snakefile() override { return ""; }
virtual std::string load_snakefile() override
{
return snakefile;
}
};
struct ExecutorMock: public Executor {
std::vector<std::string> history;
virtual std::string execute(std::string const& command) override
{
history.push_back(command);
return "";
}
};
class InterpreterTest
{
public:
explicit InterpreterTest() {}
virtual ~InterpreterTest() {}
std::vector<std::string>
test_run(std::string const& snakefile,
std::vector<std::filesystem::path> const& modified)
{
auto state = std::make_shared<StateMock>(modified);
auto loader = std::make_shared<LoaderMock>(snakefile);
auto executor = std::make_shared<ExecutorMock>();
std::stringstream ss;
Interpreter interpreter {state, loader, executor, ss};
interpreter.run();
return executor->history;
}
void test_contains(std::string const& str, std::vector<std::string> vec)
{
INFO("'" << str << "' not found, got '" << vec[0] << "'");
REQUIRE(std::find(std::begin(vec), std::end(vec), str)
!= std::end(vec));
}
2023-10-14 19:20:39 +00:00
void test_not_contains(std::string const& str, std::vector<std::string> vec)
{
INFO("'" << str << "' found");
REQUIRE(std::find(std::begin(vec), std::end(vec), str)
== std::end(vec));
}
protected:
};
TEST_CASE_METHOD(InterpreterTest, "Interpreter_simple_var")
{
std::stringstream ss;
ss << "$X = a" << std::endl;
ss << "b -> $X {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("executed", res);
}
2023-10-14 15:55:51 +00:00
TEST_CASE_METHOD(InterpreterTest, "Interpreter_array_var")
{
SECTION("value")
{
std::stringstream ss;
ss << "$X = (a b c)" << std::endl;
ss << "res -> a {" << std::endl;
ss << "$X" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("a b c", res);
}
SECTION("as dep")
{
std::stringstream ss;
ss << "$X = (a b c)" << std::endl;
ss << "z -> $X {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
SECTION("a")
{
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("executed", res);
}
SECTION("b")
{
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
test_contains("executed", res);
}
SECTION("c")
{
auto res = TEST_RUN(ss.str(), std::filesystem::path("c"));
test_contains("executed", res);
}
}
SECTION("direct use of array")
{
std::stringstream ss;
ss << "z -> (a b c) {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
SECTION("a")
{
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("executed", res);
}
SECTION("b")
{
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
test_contains("executed", res);
}
SECTION("c")
{
auto res = TEST_RUN(ss.str(), std::filesystem::path("c"));
test_contains("executed", res);
}
}
}
2023-10-14 19:20:39 +00:00
TEST_CASE_METHOD(InterpreterTest, "Interpreter_array_index")
{
SECTION("get second: ok")
{
std::stringstream ss;
ss << "$X = (a b c)" << std::endl;
ss << "d -> $X[1] {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
test_contains("executed", res);
}
SECTION("get second: not ok")
{
std::stringstream ss;
ss << "$X = (a b c)" << std::endl;
ss << "d -> $X[1] {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_not_contains("executed", res);
}
SECTION("get last: ok")
{
std::stringstream ss;
ss << "$X = (a b c)" << std::endl;
ss << "d -> $X[-1] {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("c"));
test_contains("executed", res);
}
SECTION("get last: not ok")
{
std::stringstream ss;
ss << "$X = (a b c)" << std::endl;
ss << "d -> $X[-1] {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
test_not_contains("executed", res);
}
}
2023-10-14 20:07:36 +00:00
TEST_CASE_METHOD(InterpreterTest, "Interpreter_array_literal_index")
2023-10-14 19:20:39 +00:00
{
SECTION("get second: ok")
{
std::stringstream ss;
ss << "$X = (a b c)[1]" << std::endl;
ss << "d -> $X {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
test_contains("executed", res);
}
SECTION("get second: not ok")
{
std::stringstream ss;
ss << "$X = (a b c)[1]" << std::endl;
ss << "d -> $X {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_not_contains("executed", res);
}
SECTION("get last: ok")
{
std::stringstream ss;
ss << "$X = (a b c)[-1]" << std::endl;
ss << "d -> $X {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("c"));
test_contains("executed", res);
}
SECTION("get last: not ok")
{
std::stringstream ss;
ss << "$X = (a b c)[-1]" << std::endl;
ss << "d -> $X {" << std::endl;
ss << "executed" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
test_not_contains("executed", res);
}
}
2023-10-14 20:07:36 +00:00
TEST_CASE_METHOD(InterpreterTest, "Interpreter_select_ext")
{
SECTION("on var")
{
std::stringstream ss;
ss << "$Y = g.h" << std::endl;
ss << "d -> a {" << std::endl;
ss << "$Y $Y[.hpp] $Y[.cpp]" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("g.h g.hpp g.cpp", res);
}
SECTION("on array")
{
std::stringstream ss;
ss << "$Y = (x.c y.c z.d)" << std::endl;
ss << "d -> a {" << std::endl;
ss << "$Y[.cpp]" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("x.cpp y.cpp z.cpp", res);
}
}
TEST_CASE_METHOD(InterpreterTest, "Interpreter_replace_ext")
{
SECTION("on array")
{
std::stringstream ss;
ss << "$Y = (x.c y.c z.d w t.h)" << std::endl;
ss << "d -> a {" << std::endl;
ss << "$Y[.c=.h]" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("x.h y.h z.d w t.h", res);
}
}
TEST_CASE_METHOD(InterpreterTest, "Interpreter_in_out")
{
SECTION("on array")
{
std::stringstream ss;
ss << "x y z -> a b c {" << std::endl;
ss << "$IN $OUT" << std::endl;
ss << "}" << std::endl;
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
test_contains("a b c x y z", res);
}
}