package de.renew.formalism.function;

import org.junit.jupiter.api.Test;

import de.renew.unify.Impossible;
import de.renew.unify.Tuple;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class FieldWriteFunctionTest {
    @Test
    public void testFunction() throws NoSuchFieldException, Impossible {
        //given
        final TestClass testObject = new TestClass();
        final String valueToSet = "Test String";
        final Object[] testValues = { testObject, valueToSet };
        final Tuple testTuple = new Tuple(testValues, null);
        final FieldWriteFunction testFieldWriteFunction =
            new FieldWriteFunction(TestClass.class.getField("_objToPass"));
        //when
        final Object actualOutput = testFieldWriteFunction.function(testTuple);
        //then
        assertEquals(testObject._objToPass, actualOutput);
        assertEquals(valueToSet, testObject._objToPass);
    }

    @Test
    public void testFunctionException() throws NoSuchFieldException {
        //given
        final TestClass testObject = new TestClass();
        final Object[] testValues = { testObject, null };
        final Tuple testTuple = new Tuple(testValues, null);
        final FieldWriteFunction testFieldWriteFunction =
            new FieldWriteFunction(TestClass.class.getField("_objToNotPass"));
        final String exceptionMessage =
            "Exception occured during method call: java.lang.IllegalArgumentException:"
                + " Can not set int field de.renew.formalism.function.FieldWriteFunctionTest$TestClass._objToNotPass to null value";
        //when
        final Exception thrown = assertThrows(Impossible.class, () -> {
            testFieldWriteFunction.function(testTuple);
        });
        //then
        assertEquals(exceptionMessage, thrown.getMessage());
    }

    public static class TestClass {
        public String _objToPass = "randomString";
        public int _objToNotPass = 4;
    }
}
