#include #include "fiko/cekirdek/cekirdek.hpp" #include "fiko_test.hpp" using namespace fiko; namespace { // hesapla() cagrildiginda kimligini paylasilan iz vektorune ekleyen sahte // nesne. bagimliliklar() sabit girdi listesi dondurur (feature DAG kenari). struct IzNesne : DokumanNesnesi { std::vector* iz; std::vector girdiler; IzNesne(Varlik k, std::vector* izVek, std::vector g) : DokumanNesnesi(k), iz(izVek), girdiler(std::move(g)) {} const char* turAdi() const override { return "Iz"; } std::string ad() const override { return "Iz." + std::to_string(kimlik_); } std::vector bagimliliklar() const override { return girdiler; } void hesapla(Dunya&, OlayGunlugu&) override { iz->push_back(kimlik_); } }; // iz icinde a, b'den once mi? (topolojik dogrulama) bool oncedir(const std::vector& iz, Varlik a, Varlik b) { int ia = -1, ib = -1; for (int i = 0; i < static_cast(iz.size()); ++i) { if (iz[i] == a) ia = i; if (iz[i] == b) ib = i; } return ia >= 0 && ib >= 0 && ia < ib; } } // namespace FIKO_TEST(recompute_topolojik_sira) { Cekirdek c; std::vector iz; // A (girdisiz), B (A'ya bagimli). B hesaplaninca A once gelmeli. const Varlik a = c.dunya().olustur(); const Varlik b = c.dunya().olustur(); c.nesneEkle(std::make_unique(a, &iz, std::vector{})); c.nesneEkle(std::make_unique(b, &iz, std::vector{a})); c.recompute().kirlet(c, a); // A kirli → B (bagimli) da kirlenmeli FIKO_KONTROL(c.recompute().kirliVar()); FIKO_KONTROL(c.recompute().kirli().count(b) == 1); c.recompute().hesapla(c, c.olaylar()); FIKO_KONTROL(iz.size() == 2); FIKO_KONTROL(oncedir(iz, a, b)); // A, B'den once hesaplandi FIKO_KONTROL(!c.recompute().kirliVar()); // kirli seti temizlendi } FIKO_TEST(recompute_hesaplama_bitti_yayinlar) { Cekirdek c; std::vector iz; u32 sonSayi = 999; c.olaylar().abone( [&sonSayi](const HesaplamaBitti& o) { sonSayi = o.sayi; }); const Varlik a = c.dunya().olustur(); c.nesneEkle(std::make_unique(a, &iz, std::vector{})); c.recompute().kirlet(c, a); c.recompute().hesapla(c, c.olaylar()); FIKO_KONTROL(sonSayi == 1); // 1 nesne hesaplandi // Kirli yokken hesapla no-op: HesaplamaBitti yayinlanmamali. sonSayi = 999; c.recompute().hesapla(c, c.olaylar()); FIKO_KONTROL(sonSayi == 999); } FIKO_TEST(recompute_cevrim_atlanir) { Cekirdek c; std::vector iz; // A → B → A dongusu. Cevrim tespit edilmeli; cokme/sonsuz dongu olmamali. const Varlik a = c.dunya().olustur(); const Varlik b = c.dunya().olustur(); c.nesneEkle(std::make_unique(a, &iz, std::vector{b})); c.nesneEkle(std::make_unique(b, &iz, std::vector{a})); c.recompute().kirlet(c, a); // ikisi de kirli FIKO_KONTROL(c.recompute().kirli().count(a) == 1); FIKO_KONTROL(c.recompute().kirli().count(b) == 1); c.recompute().hesapla(c, c.olaylar()); // sonsuz dongu YOK // Her iki nesne de hesaplanir (cevrim bir kenari kirar, dugumler atlanmaz). FIKO_KONTROL(iz.size() == 2); FIKO_KONTROL(!c.recompute().kirliVar()); } FIKO_TEST(recompute_zincir_sira) { Cekirdek c; std::vector iz; // A ← B ← C zinciri (C, B'ye; B, A'ya bagimli). C kirlenince A,B de. const Varlik a = c.dunya().olustur(); const Varlik b = c.dunya().olustur(); const Varlik cc = c.dunya().olustur(); c.nesneEkle(std::make_unique(a, &iz, std::vector{})); c.nesneEkle(std::make_unique(b, &iz, std::vector{a})); c.nesneEkle(std::make_unique(cc, &iz, std::vector{b})); c.recompute().kirlet(c, a); // A kirli → B,C zincirle kirlenir c.recompute().hesapla(c, c.olaylar()); FIKO_KONTROL(iz.size() == 3); FIKO_KONTROL(oncedir(iz, a, b)); FIKO_KONTROL(oncedir(iz, b, cc)); }