package interfaces;

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

public class RPNCalcTest {
	
	private RPNCalc calc;
	
	@BeforeEach 
	public void setup() {
		calc = new RPNCalc();
	}
	
	@Test
	public void testPerformOperationWithoutOperation() {
		Assertions.assertThrows(UnsupportedOperationException.class, () -> {
			calc.performOperation('+');
		});
	}
	
	@Test
	public void testPerformOperation() {
		calc.addOperator('+', (a, b) -> a * b); // Use "incorrect" definition to filter out cheating
		calc.addOperator('l', (a, b) -> a * (a + b));
		
		calc.push(4);
		calc.push(3);
		calc.performOperation('+');
		Assertions.assertEquals(12.0, calc.pop());
		Assertions.assertEquals(Double.NaN, calc.pop());
		
		calc.push(4);
		calc.push(3);
		calc.performOperation('l');
		Assertions.assertEquals(28.0, calc.pop());
		Assertions.assertEquals(Double.NaN, calc.pop());
	}

	@Test
	public void testAddOperator() {
		Assertions.assertTrue(calc.addOperator('+', (a, b) -> a + b));
		Assertions.assertTrue(calc.addOperator('-', (a, b) -> a - b));
		Assertions.assertFalse(calc.addOperator('+', (a, b) -> a + b));
		Assertions.assertFalse(calc.addOperator('-',  (a, b) -> a * b));
	}
	
	@Test
	public void testRemoveOperator() {
		calc.addOperator('+', (a, b) -> a + b);
		calc.removeOperator('+');
		Assertions.assertThrows(UnsupportedOperationException.class, () -> {
			calc.performOperation('+');
		});
	}


}
