#include "fiko/cekirdek/cekirdek.hpp" #include "fiko_test.hpp" using namespace fiko; namespace { // Katkılarını registry'lere kaydeden sahte modül struct SahteModul : Modul { int kurSayaci = 0; const char* kimlik() const override { return "sahte"; } const char* ad() const override { return "Sahte"; } void kur(Cekirdek& c) override { ++kurSayaci; c.paneller().ekle({"sahte_panel", "Sahte Panel", 0, [](Cekirdek&) {}, true}); c.menuler().ekle({"Test", "Sahte Eylem", "★", 0, [](Cekirdek&) {}, nullptr}); c.agac().ekle([](Cekirdek&, std::vector& kok) { kok.push_back({"Sahte Kök", VARLIK_YOK, {}}); }); } }; } FIKO_TEST(cekirdek_modul_kur_bir_kez) { Cekirdek c; auto m = std::make_unique(); SahteModul* ham = m.get(); c.modulEkle(std::move(m)); FIKO_KONTROL(ham->kurSayaci == 0); // modulEkle henüz kur etmez c.moduleriKur(); FIKO_KONTROL(ham->kurSayaci == 1); c.moduleriKur(); // ikinci çağrı yeniden kur ETMEMELİ FIKO_KONTROL(ham->kurSayaci == 1); FIKO_KONTROL(c.moduller().size() == 1); } FIKO_TEST(cekirdek_registry_katkilari_gorunur) { Cekirdek c; c.modulEkle(std::make_unique()); c.moduleriKur(); FIKO_KONTROL(c.paneller().hepsi().size() == 1); FIKO_KONTROL(c.paneller().bul("sahte_panel") != nullptr); FIKO_KONTROL(c.menuler().hepsi().size() == 1); FIKO_KONTROL(c.menuler().gruplar().size() == 1); std::vector kok; c.agac().topla(c, kok); FIKO_KONTROL(kok.size() == 1); FIKO_KONTROL(kok[0].etiket == "Sahte Kök"); } FIKO_TEST(cekirdek_arac_etkinlestir) { Cekirdek c; int acilan = 0, kapanan = 0; c.araclar().ekle({"a", "Araç A", [&](Cekirdek&) { ++acilan; }, [&](Cekirdek&) { ++kapanan; }}); c.araclar().ekle({"b", "Araç B", [&](Cekirdek&) { ++acilan; }, [&](Cekirdek&) { ++kapanan; }}); c.araclar().etkinlestir(c, "a"); FIKO_KONTROL(acilan == 1 && kapanan == 0); c.araclar().etkinlestir(c, "b"); // a pasifleş, b etkinleş FIKO_KONTROL(acilan == 2 && kapanan == 1); FIKO_KONTROL(c.araclar().aktif() == "b"); c.araclar().etkinlestir(c, "b"); // zaten aktif — no-op FIKO_KONTROL(acilan == 2 && kapanan == 1); } // ---- Merkezi komut dispatch (lisans gate + KomutCalisti denetim olayı) ---- FIKO_TEST(komut_calistir_temel_ve_olay) { Cekirdek c; int calisti = 0; MenuOge oge{"Geometri", "Kutu Ekle", "◼", 0, [&](Cekirdek&) { ++calisti; }}; // KomutCalisti olayına abone ol → merkezden geçtiğini + doğru payload'u doğrula. std::string sonAd, sonKaynak, sonKat; bool sonBasarili = false; int olaySayi = 0; c.olaylar().abone([&](const KomutCalisti& o) { sonAd = o.ad; sonKaynak = o.kaynak; sonKat = o.kategori; sonBasarili = o.basarili; ++olaySayi; }); const bool r = c.komutCalistir(oge, "palet"); FIKO_KONTROL(r && calisti == 1); FIKO_KONTROL(olaySayi == 1 && sonAd == "Kutu Ekle" && sonKat == "Geometri"); FIKO_KONTROL(sonKaynak == "palet" && sonBasarili); } FIKO_TEST(komut_calistir_lisans_gate_engeller) { Cekirdek c; int calisti = 0; MenuOge oge{"Pro", "Gelişmiş", "★", 0, [&](Cekirdek&) { ++calisti; }}; c.lisansKapisiAyarla([](const MenuOge& o) { return o.grup != "Pro"; }); // Pro reddet bool olayBasarili = true; c.olaylar().abone([&](const KomutCalisti& o) { olayBasarili = o.basarili; }); const bool r = c.komutCalistir(oge, "menu"); FIKO_KONTROL(!r && calisti == 0); // lisans reddi → çalışmadı FIKO_KONTROL(!olayBasarili); // denied olayı yine yayınlandı (denetim) } FIKO_TEST(komut_calistir_etkinMi_false_engeller) { Cekirdek c; int calisti = 0; MenuOge oge{"Test", "Pasif", "·", 0, [&](Cekirdek&) { ++calisti; }, [](Cekirdek&) { return false; }}; // etkinMi=false const bool r = c.komutCalistir(oge, "menu"); FIKO_KONTROL(!r && calisti == 0); } FIKO_TEST(komut_calistir_menu_degistirse_guvenli) { // Komut çalıştırma SIRASINDA menü kaydına ekler → vector realloc → menuler().hepsi() // içindeki `oge` referansı dangling olur. komutCalistir ad/kategori/calistir'ı ÖNCE // kopyaladığı için güvenli (dangling okuma / çalışan std::function yıkımı YOK). Cekirdek c; std::string sonAd; c.olaylar().abone([&](const KomutCalisti& o) { sonAd = o.ad; }); c.menuler().ekle({"Test", "Kendini Degistir", "·", 0, [](Cekirdek& ck) { for (int i = 0; i < 100; ++i) ck.menuler().ekle({"Dinamik", "Oge" + std::to_string(i), "", 0, [](Cekirdek&) {}}); }}); const MenuOge& ref = c.menuler().hepsi()[0]; // menuler_ vector'üne referans const bool r = c.komutCalistir(ref, "test"); // calistir realloc → ref dangling olur FIKO_KONTROL(r); FIKO_KONTROL(sonAd == "Kendini Degistir"); // event kopyadan → doğru (dangling okumaz) }