#include "src/camellya.h" #include using namespace camellya; TEST_CASE("VM - Basic arithmetic", "[vm]") { Camellya state; SECTION("Addition") { REQUIRE(state.do_string("var x = 10 + 20;")); auto x = state.get_global("x"); REQUIRE(x != nullptr); REQUIRE(x->type() == Type::NUMBER); REQUIRE(std::dynamic_pointer_cast(x)->value == 30.0); } SECTION("Subtraction") { REQUIRE(state.do_string("var y = 50 - 15;")); auto y = state.get_global("y"); REQUIRE(y != nullptr); REQUIRE(std::dynamic_pointer_cast(y)->value == 35.0); } SECTION("Multiplication") { REQUIRE(state.do_string("var z = 7 * 8;")); auto z = state.get_global("z"); REQUIRE(z != nullptr); REQUIRE(std::dynamic_pointer_cast(z)->value == 56.0); } SECTION("Division") { REQUIRE(state.do_string("var w = 100 / 4;")); auto w = state.get_global("w"); REQUIRE(w != nullptr); REQUIRE(std::dynamic_pointer_cast(w)->value == 25.0); } } TEST_CASE("VM - Variables and assignment", "[vm]") { Camellya state; SECTION("Variable declaration and initialization") { REQUIRE(state.do_string("var a = 42;")); auto a = state.get_global("a"); REQUIRE(a != nullptr); REQUIRE(std::dynamic_pointer_cast(a)->value == 42.0); } SECTION("Variable assignment") { REQUIRE(state.do_string(R"( var b = 10; b = 20; )")); auto b = state.get_global("b"); REQUIRE(std::dynamic_pointer_cast(b)->value == 20.0); } } TEST_CASE("VM - String operations", "[vm]") { Camellya state; SECTION("String concatenation") { REQUIRE(state.do_string(R"(var greeting = "Hello" + " " + "World";)")); auto greeting = state.get_global("greeting"); REQUIRE(greeting != nullptr); REQUIRE(greeting->type() == Type::STRING); REQUIRE(std::dynamic_pointer_cast(greeting)->value == "Hello World"); } } TEST_CASE("VM - Comparison operators", "[vm]") { Camellya state; SECTION("Equality") { REQUIRE(state.do_string("var eq = 10 == 10;")); auto eq = state.get_global("eq"); REQUIRE(std::dynamic_pointer_cast(eq)->value == true); } SECTION("Greater than") { REQUIRE(state.do_string("var gt = 20 > 10;")); auto gt = state.get_global("gt"); REQUIRE(std::dynamic_pointer_cast(gt)->value == true); } SECTION("Less than") { REQUIRE(state.do_string("var lt = 5 < 10;")); auto lt = state.get_global("lt"); REQUIRE(std::dynamic_pointer_cast(lt)->value == true); } } TEST_CASE("VM - Lists", "[vm]") { Camellya state; SECTION("Create list") { REQUIRE(state.do_string("var numbers = [1, 2, 3, 4, 5];")); auto numbers = state.get_global("numbers"); REQUIRE(numbers != nullptr); REQUIRE(numbers->type() == Type::LIST); auto list = std::dynamic_pointer_cast(numbers); REQUIRE(list->size() == 5); } SECTION("List indexing") { REQUIRE(state.do_string(R"( var arr = [10, 20, 30]; var item = arr[1]; )")); auto item = state.get_global("item"); REQUIRE(std::dynamic_pointer_cast(item)->value == 20.0); } } TEST_CASE("VM - Maps", "[vm]") { Camellya state; SECTION("Create map") { REQUIRE(state.do_string(R"(var person = {"name": "Alice", "age": "30"};)")); auto person = state.get_global("person"); REQUIRE(person != nullptr); REQUIRE(person->type() == Type::MAP); } SECTION("Map access") { REQUIRE(state.do_string(R"( var data = {"key": "value"}; var val = data["key"]; )")); auto val = state.get_global("val"); REQUIRE(val->type() == Type::STRING); REQUIRE(std::dynamic_pointer_cast(val)->value == "value"); } } TEST_CASE("VM - If statements", "[vm]") { Camellya state; SECTION("If branch taken") { REQUIRE(state.do_string(R"( var x = 10; if (x > 5) { x = 100; } )")); auto x = state.get_global("x"); REQUIRE(std::dynamic_pointer_cast(x)->value == 100.0); } SECTION("Else branch taken") { REQUIRE(state.do_string(R"( var y = 3; if (y > 5) { y = 100; } else { y = 200; } )")); auto y = state.get_global("y"); REQUIRE(std::dynamic_pointer_cast(y)->value == 200.0); } } TEST_CASE("VM - While loops", "[vm]") { Camellya state; SECTION("While loop") { REQUIRE(state.do_string(R"( var counter = 0; var sum = 0; while (counter < 5) { sum = sum + counter; counter = counter + 1; } )")); auto sum = state.get_global("sum"); REQUIRE(std::dynamic_pointer_cast(sum)->value == 10.0); } } TEST_CASE("VM - Native functions", "[vm]") { Camellya state; SECTION("len function") { REQUIRE(state.do_string(R"( var arr = [1, 2, 3, 4]; var size = len(arr); )")); auto size = state.get_global("size"); REQUIRE(std::dynamic_pointer_cast(size)->value == 4.0); } }