import java.util.List;

public class ContohUnitTest {

    // ---- unit produksi: fungsi murni tanpa dependensi eksternal ----

    static double celsiusKeFahrenheit(double celsius) {
        return celsius * 9.0 / 5.0 + 32.0;
    }

    static String kategoriSuhu(double celsius) {
        if (celsius <= 0) {
            return "beku";
        }
        if (celsius < 100) {
            return "cair";
        }
        return "uap";
    }

    // ---- assertion minimal ala framework ----

    private static void cekSama(Object diharapkan, Object aktual, String namaUji) {
        if (!diharapkan.equals(aktual)) {
            throw new AssertionError(namaUji + ": diharapkan '"
                + diharapkan + "' tetapi aktual '" + aktual + "'");
        }
    }

    // ---- method uji: satu perilaku per method ----

    static void titikBekuMenghasilkan32F() {
        double masukan = 0.0;                                // arrange
        double hasil = celsiusKeFahrenheit(masukan);         // act
        cekSama(32.0, hasil, "titik beku");                  // assert
    }

    static void titikDidihMenghasilkan212F() {
        double hasil = celsiusKeFahrenheit(100.0);
        cekSama(212.0, hasil, "titik didih");
    }

    static void minus40SamaDiKeduaSkala() {
        double hasil = celsiusKeFahrenheit(-40.0);
        cekSama(-40.0, hasil, "minus 40");
    }

    static void suhuNegatifDikategorikanBeku() {
        String kategori = kategoriSuhu(-5.0);
        cekSama("beku", kategori, "kategori beku");
    }

    static void suhuHangatDikategorikanCair() {
        String kategori = kategoriSuhu(60.0);
        cekSama("cair", kategori, "kategori cair");
    }

    static void suhuDiAtasDidihDikategorikanUap() {
        String kategori = kategoriSuhu(120.0);
        cekSama("uap", kategori, "kategori uap");
    }

    // ---- penjalan sederhana ----

    record Uji(String nama, Runnable blok) {}

    public static void main(String[] args) {
        List<Uji> suite = List.of(
            new Uji("titikBekuMenghasilkan32F", ContohUnitTest::titikBekuMenghasilkan32F),
            new Uji("titikDidihMenghasilkan212F", ContohUnitTest::titikDidihMenghasilkan212F),
            new Uji("minus40SamaDiKeduaSkala", ContohUnitTest::minus40SamaDiKeduaSkala),
            new Uji("suhuNegatifDikategorikanBeku", ContohUnitTest::suhuNegatifDikategorikanBeku),
            new Uji("suhuHangatDikategorikanCair", ContohUnitTest::suhuHangatDikategorikanCair),
            new Uji("suhuDiAtasDidihDikategorikanUap", ContohUnitTest::suhuDiAtasDidihDikategorikanUap)
        );

        int lulus = 0;
        int gagal = 0;
        for (Uji uji : suite) {
            try {
                uji.blok().run();
                lulus++;
                System.out.println("LULUS  " + uji.nama());
            } catch (AssertionError e) {
                gagal++;
                System.out.println("GAGAL  " + uji.nama() + " -> " + e.getMessage());
            }
        }
        System.out.println("ringkasan: " + lulus + " lulus, " + gagal + " gagal");
    }
}
