package de.renew.formalism.function;

import org.junit.jupiter.api.Test;

import de.renew.unify.Impossible;
import de.renew.util.Value;

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


public class DynamicFieldFunctionTest {

    @Test
    public void testFunction() throws NoSuchFieldException, Impossible {
        //given
        String testField = "length";
        DynamicFieldFunction testDynamicFieldFunction = new DynamicFieldFunction(testField);
        int[] integerArray = new int[] { 1, 2, 3, 4, 5 };
        //when
        Object expectedObject = testDynamicFieldFunction.function(integerArray);
        //then
        assertTrue(expectedObject instanceof Value);
        assertEquals(((Value) expectedObject).value, 5);
    }

    @Test
    public void testFunctionException() throws NoSuchFieldException, Impossible {
        //given
        String testField = "something else";
        DynamicFieldFunction testDynamicFieldFunction = new DynamicFieldFunction(testField);
        int[] integerArray = new int[] { 1, 2, 3, 4, 5 };
        String expectedExceptionMessage =
            "Exception occurred during dynamic field access (something else on object "
                + integerArray + "): de.renew.unify.Impossible";
        //when
        Impossible thrown = assertThrows(Impossible.class, () -> {
            testDynamicFieldFunction.function(integerArray);
        });
        //then
        assertEquals(expectedExceptionMessage, thrown.getMessage());
    }

    @Test
    public void testToString() {
        //given
        DynamicFieldFunction testDynamicFieldFunction = new DynamicFieldFunction("testString");
        //when
        String actualOutput = testDynamicFieldFunction.toString();
        //then
        assertEquals("DynFieldFunc(testString)", actualOutput);
    }
}
