#include #include "fiko/ayar/ayar_sistemi.hpp" #include "fiko_test.hpp" using namespace fiko; using namespace fiko::ayar; namespace { // Canlı duruma bağlı örnek kayıt seti kuran yardımcı (her test taze sistem kullanır). struct Ortam { AyarSistemi s; bool bayrak = true; i64 sayi = 6; f64 oran = 0.32; Vec3f renk{1.0f, 0.45f, 0.05f}; std::string tema = "Koyu"; Ortam() { s.ayarKaydet({.kimlik = "test.bayrak", .kategori = "Genel", .ad = "Bayrak", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [this] { return dBool(bayrak); }, .ata = [this](const AyarDeger& d) { bayrak = d.b; }}); s.ayarKaydet({.kimlik = "test.sayi", .kategori = "Genel", .ad = "Sayı", .tip = AyarTip::Int, .varsayilan = dInt(6), .min = 3, .maks = 20, .al = [this] { return dInt(sayi); }, .ata = [this](const AyarDeger& d) { sayi = d.i; }}); s.ayarKaydet({.kimlik = "test.oran", .kategori = "Aydınlatma", .ad = "Oran", .tip = AyarTip::F64, .varsayilan = dF(0.32), .min = 0, .maks = 1, .al = [this] { return dF(oran); }, .ata = [this](const AyarDeger& d) { oran = d.f; }}); s.ayarKaydet({.kimlik = "test.renk", .kategori = "Aydınlatma", .ad = "Renk", .tip = AyarTip::Renk, .varsayilan = dRenk({1.0f, 0.45f, 0.05f}), .al = [this] { return dRenk(renk); }, .ata = [this](const AyarDeger& d) { renk = d.renk; }}); s.ayarKaydet({.kimlik = "test.tema", .kategori = "Görünüm", .ad = "Tema", .tip = AyarTip::Secenek, .varsayilan = dMetin("Koyu"), .secenekler = {"Koyu", "Neon", "Açık"}, .al = [this] { return dMetin(tema); }, .ata = [this](const AyarDeger& d) { tema = d.metin; }}); } }; } // namespace FIKO_TEST(ayar_kayit_ve_gez) { Ortam o; FIKO_KONTROL(o.s.hepsi().size() == 5); FIKO_KONTROL(o.s.bul("test.sayi") != nullptr); FIKO_KONTROL(o.s.bul("yok.kimlik") == nullptr); // Kategoriler ilk kayıt sırasıyla ve tekrarsız. const auto kat = o.s.kategoriler(); FIKO_KONTROL(kat.size() == 3); FIKO_KONTROL(kat[0] == "Genel" && kat[1] == "Aydınlatma" && kat[2] == "Görünüm"); int adet = 0; o.s.gez("Aydınlatma", [&](const AyarTanim&) { ++adet; }); FIKO_KONTROL(adet == 2); adet = 0; o.s.gez("", [&](const AyarTanim&) { ++adet; }); FIKO_KONTROL(adet == 5); // Bağsız tanım reddedilir; aynı kimlik üzerine yazar (boyut artmaz). o.s.ayarKaydet({.kimlik = "bagsiz", .kategori = "Genel", .ad = "X"}); FIKO_KONTROL(o.s.hepsi().size() == 5); o.s.ayarKaydet({.kimlik = "test.bayrak", .kategori = "Genel", .ad = "Bayrak2", .tip = AyarTip::Bool, .varsayilan = dBool(true), .al = [&o] { return dBool(o.bayrak); }, .ata = [&o](const AyarDeger& d) { o.bayrak = d.b; }}); FIKO_KONTROL(o.s.hepsi().size() == 5); FIKO_KONTROL(o.s.bul("test.bayrak")->ad == "Bayrak2"); } FIKO_TEST(ayar_deger_ata_ve_degisti) { Ortam o; int bildirim = 0; std::string sonKimlik; o.s.degisti = [&](const AyarTanim& t, const AyarDeger&) { ++bildirim; sonKimlik = t.kimlik; }; FIKO_KONTROL(o.s.degerAta("test.oran", dF(0.75))); FIKO_YAKIN(o.oran, 0.75, 1e-12); // canlı duruma anında uygulandı FIKO_KONTROL(bildirim == 1 && sonKimlik == "test.oran"); FIKO_KONTROL(!o.s.degerAta("yok.kimlik", dF(1.0))); FIKO_KONTROL(bildirim == 1); FIKO_KONTROL(o.s.degistiMi(*o.s.bul("test.oran"))); FIKO_KONTROL(!o.s.degistiMi(*o.s.bul("test.bayrak"))); // sifirla: varsayılana dön + bildirim. FIKO_KONTROL(o.s.sifirla("test.oran")); FIKO_YAKIN(o.oran, 0.32, 1e-12); FIKO_KONTROL(bildirim == 2); FIKO_KONTROL(!o.s.degistiMi(*o.s.bul("test.oran"))); // kategoriSifirla: yalnız o kategori. o.s.degerAta("test.oran", dF(0.9)); o.s.degerAta("test.sayi", dInt(12)); FIKO_KONTROL(o.s.kategoriSifirla("Aydınlatma") == 2); FIKO_YAKIN(o.oran, 0.32, 1e-12); FIKO_KONTROL(o.sayi == 12); // Genel kategorisine dokunulmadı } FIKO_TEST(ayar_deger_metni_ve_coz) { Ortam o; const AyarTanim& renk = *o.s.bul("test.renk"); const AyarTanim& tema = *o.s.bul("test.tema"); const AyarTanim& bayrak = *o.s.bul("test.bayrak"); FIKO_KONTROL(AyarSistemi::degerMetni(bayrak, dBool(false)) == "0"); FIKO_KONTROL(AyarSistemi::degerMetni(*o.s.bul("test.sayi"), dInt(42)) == "42"); FIKO_KONTROL(AyarSistemi::degerMetni(renk, dRenk({0.5f, 0.25f, 1.0f})) == "0.5,0.25,1"); AyarDeger d; FIKO_KONTROL(AyarSistemi::degerCoz(renk, "0.1, 0.2 ,0.3", d)); FIKO_YAKIN(d.renk.y, 0.2f, 1e-5f); FIKO_KONTROL(!AyarSistemi::degerCoz(renk, "0.1,0.2", d)); // eksik bileşen FIKO_KONTROL(!AyarSistemi::degerCoz(renk, "a,b,c", d)); // sayı değil FIKO_KONTROL(AyarSistemi::degerCoz(tema, "Neon", d) && d.metin == "Neon"); FIKO_KONTROL(!AyarSistemi::degerCoz(tema, "Mor", d)); // bilinmeyen seçenek FIKO_KONTROL(AyarSistemi::degerCoz(bayrak, "true", d) && d.b); FIKO_KONTROL(!AyarSistemi::degerCoz(bayrak, "belki", d)); } FIKO_TEST(ayar_serilestir_yukle_roundtrip) { Ortam o; FIKO_KONTROL(o.s.serilestir().empty()); // hiçbir şey değişmedi → boş o.s.degerAta("test.bayrak", dBool(false)); o.s.degerAta("test.oran", dF(0.618)); o.s.degerAta("test.renk", dRenk({0.2f, 0.4f, 0.6f})); o.s.degerAta("test.tema", dMetin("Neon")); const std::string metin = o.s.serilestir(); FIKO_KONTROL(metin.find("test.bayrak=0") != std::string::npos); FIKO_KONTROL(metin.find("test.tema=Neon") != std::string::npos); FIKO_KONTROL(metin.find("test.sayi=") == std::string::npos); // değişmedi → yazılmaz // Taze ortam: yükleme değerleri sessizce (degisti çağrılmadan) uygular. Ortam o2; int bildirim = 0; o2.s.degisti = [&](const AyarTanim&, const AyarDeger&) { ++bildirim; }; FIKO_KONTROL(o2.s.yukle(metin) == 4); FIKO_KONTROL(bildirim == 0); FIKO_KONTROL(o2.bayrak == false); FIKO_YAKIN(o2.oran, 0.618, 1e-6); FIKO_YAKIN(o2.renk.z, 0.6f, 1e-4f); FIKO_KONTROL(o2.tema == "Neon"); // İkinci serileştirme aynı içeriği üretir (kararlı round-trip). FIKO_KONTROL(o2.s.serilestir() == metin); // Bozuk/bilinmeyen satırlar atlanır, geçerliler uygulanır. Ortam o3; FIKO_KONTROL(o3.s.yukle("yok.kimlik=5\ntest.sayi=abc\n=bos\ntest.sayi=9\n") == 1); FIKO_KONTROL(o3.sayi == 9); }