package p07_funkcje;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class FunkcjeTest {

	@Test
	void testSilnia0() {
		// normalnie w testach nie robi się żadnych printów
		// tu tylko eksperyment, żeby zobaczyć, że ten kod naprawdę się wykonuje
		System.out.println("a kuku");
		
		// W typowym teście wykonujemy scenariusz testowy - tutaj tylko wywołanie funkcji, ale bywają bardziej rozbudowane przykłady
		long wynik = p07_funkcje.Funkcje.silnia(0);
		
		// A pod koniec testu za pomocą asercji sprawdzamy czy kod zadziałał prawidłowo.
		// Tutaj sprawdzamy wynik, ale często sprawdza się też stan obiektów itp. rzeczy
		
		// W języku Java istnieje prosta konstrukcja assert:
		// assert wynik == 1;
		// ale rzadko się jej używa, bo daje marne komunikaty w razie błędu; tylko numer linii
		// można podać własny komunikat, ale jest to dużo roboty:
		// assert wynik == 1 : "dla silnia 0 wyszedł zły wynik " + wynik;
		
		// Najczęście używa się assertEquals pochodzącej z biblioteki JUnit,
		assertEquals(1, wynik);
		
		// albo dedykowanych bibliotek do pisania asercji, np. AssertJ
		
		// Technicznie to działa tak:
		// - gdy asercja stwierdza, że warunek jest spełniony (jest OK), to nic się dzieje i test idzie dalej
		// - gdy asercja stwierdza, że warunek nie jest spełniony, coś się nie zgadza,
		//   to wyrzucany jest wyjątek AssertionError i dalsza część testu się nie wykona
		// Gdy cały test dojdzie do końca bez wyjątku, to jest sukces.
		// Gdy test kończy się wyjątkiem AssertionError - to "failuje"
		// Gdy test kończy się innym wyjątkiem (np. NPE) - jest to liczone jako "error"
	}
	
	@Test
	void testSilnia5() {
		long wynik = p07_funkcje.Funkcje.silnia(5);
		assertEquals(120, wynik);
	}

	@Test
	void testFib1() {
		long wynik = p07_funkcje.Funkcje.fib(1);
		assertEquals(1, wynik);
	}

	@Test
	void testFib10() {
		long wynik = p07_funkcje.Funkcje.fib(10);
		assertEquals(55, wynik);
	}

}
