#ifdef TESTS_BUILD
#include <catch.hpp>
#include "../src/Script.hpp"
using namespace Porygon;

TEST_CASE( "Numerical for loop without step", "[integration]" ) {
    auto script = Script::Create(uR"(
result = 0
for i = 0,10 do
    result = result + 3
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 33);
    delete script;
    delete var;
}

TEST_CASE( "Numerical for loop with step", "[integration]" ) {
    auto script = Script::Create(uR"(
result = 0
for i = 0,10,3 do
    result = result + 3
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 12);
    delete script;
    delete var;
}

TEST_CASE( "Numerical for loop with negative step", "[integration]" ) {
    auto script = Script::Create(uR"(
result = 0
for i = 10,0,-1 do
    result = result + 3
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 33);
    delete script;
    delete var;
}


TEST_CASE( "Numerical for loop creates variable", "[integration]" ) {
    auto script = Script::Create(uR"(
result = 0
for i = 0,5 do
    result = result + i
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 15);
    delete script;
    delete var;
}

TEST_CASE( "Numerical for loop, break", "[integration]" ) {
    auto script = Script::Create(uR"(
result = 0
for i = 0,5 do
    if i > 3 then break end
    result = result + i
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 6);
    delete script;
    delete var;
}


TEST_CASE( "Generic for loop over simple numerical table, get keys", "[integration]" ) {
    auto script = Script::Create(uR"(
local table = {1, 3, 5, 7, 9}
result = 0
for i in table do
    result = result + i
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 15);
    delete script;
    delete var;
}

TEST_CASE( "Generic for loop over simple numerical table, get values", "[integration]" ) {
    auto script = Script::Create(uR"(
local table = {1, 3, 5, 7, 9}
result = 0
for i,v in table do
    result = result + v
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 25);
    delete script;
    delete var;
}

TEST_CASE( "Generic for loop over simple numerical table, break", "[integration]" ) {
    auto script = Script::Create(uR"(
local table = {1, 3, 5, 7, 9}
result = 0
for i,v in table do
    if i > 3 then break end
    result = result + v
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 9);
    delete script;
    delete var;
}

TEST_CASE( "While loop", "[integration]" ) {
    auto script = Script::Create(uR"(
result = 0
while result < 5 do
    result = result + 1
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 5);
    delete script;
    delete var;
}

TEST_CASE( "While loop break", "[integration]" ) {
    auto script = Script::Create(uR"(
result = 0
while true do
    result = result + 1
    if result >= 5 then break end
end
)");
    REQUIRE(!script->Diagnostics -> HasErrors());
    script->Evaluate();
    auto var = script->GetVariable(u"result");
    REQUIRE(var->EvaluateInteger() == 5);
    delete script;
    delete var;
}

#endif
