package jetbrains.mps.closures.test;

/*Generated by MPS */

import org.junit.jupiter.api.Test;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.baseLanguage.closures.util.Constants;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import org.junit.Assert;

public class FunctionTypes_Test {
  @Test
  public void test_functionTypeAdapter_simple() throws Exception {
    _FunctionTypes._return_P0_E0<? extends Integer> fun1 = () -> 1;
    _FunctionTypes._return_P0_E0<? extends Integer> fun2 = fun1;
    _FunctionTypes._return_P0_E0<? extends Number> fun3 = fun1;
    fun3 = fun2;
    this.accept_int(fun1);
    this.accept_int(fun2);
    this.accept_Integer(fun2);
    this.accept_Number(fun2);
    this.accept_int(() -> 1);
    this.accept_Integer(() -> (Integer) 1);
    this.accept_Number(() -> (Integer) 1);
  }
  @Test
  public void test_exceptions() throws Exception {
    _FunctionTypes._void_P0_E1<? extends Exception> throwsException = () -> {
      throw new Exception();
    };
    _FunctionTypes._void_P0_E1<? extends InterruptedException> throwsRuntimeException = () -> {
      throw new InterruptedException();
    };
    throwsException = throwsRuntimeException;
    _FunctionTypes._void_P0_E0 throwsOne = () -> {
      throw new IllegalArgumentException();
    };
    _FunctionTypes._void_P0_E2<? extends IllegalAccessException, ? extends InterruptedException> throwsTwo = () -> {
      if (0 == 0) {
        throw new InterruptedException();
      } else {
        throw new IllegalAccessException();
      }
    };
    if (!(Constants.ONLY_CLOSURE_LITERAL_AS_FUNCTION_TYPE)) {
    }
  }
  @Test
  public void test_exceptionsYield() throws Exception {
    if (!(Constants.ONLY_CLOSURE_LITERAL_AS_FUNCTION_TYPE)) {
    }
  }
  @Test
  public void test_functionTypeAdapter_complex() throws Exception {
    _FunctionTypes._return_P1_E0<? extends Integer, ? super Integer> fun1 = (Integer i) -> i.intValue();
    _FunctionTypes._return_P1_E0<? extends Integer, ? super Integer> fun2 = (Integer i) -> Integer.valueOf(i);
    fun1 = fun2;
    fun2 = fun1;
    _FunctionTypes._return_P1_E0<? extends Integer, ? super Object> fun3 = (Object o) -> o.hashCode();
    _FunctionTypes._return_P1_E0<? extends Integer, ? super String> fun4 = (String s) -> s.length();
    fun4 = fun3;
    this.accept_int_from_int((Integer i) -> i.intValue());
    this.accept_int_from_int(fun1);
    this.accept_int_from_int(fun2);
    this.accept_int_from_Integer((Integer i) -> Integer.valueOf(i));
    this.accept_int_from_Integer(fun1);
    this.accept_int_from_Integer(fun2);
    this.accept_Integer_from_int((Integer i) -> i.intValue());
    this.accept_Integer_from_int(fun1);
    this.accept_Integer_from_int(fun2);
    this.accept_Integer_from_Object((Object o) -> o.hashCode());
    this.accept_Integer_from_Object(fun3);
    this.accept_Number_from_String((String s) -> s.length());
    this.accept_Number_from_String((Object o) -> o.hashCode());
    this.accept_Number_from_String(fun3);
    this.accept_Number_from_String(fun4);
  }
  @Test
  public void test_return_null() throws Exception {
    final Wrappers._boolean b = new Wrappers._boolean(true);
    _FunctionTypes._return_P0_E0<? extends String> ret_string = () -> {
      if (b.value) {
        return "foo";
      } else {
        return null;
      }
    };
    Assert.assertSame("foo", ret_string.invoke());
    b.value = false;
    Assert.assertNull(ret_string.invoke());
    ret_string = () -> null;
    Assert.assertNull(ret_string.invoke());
  }
  @Test
  public void test_specifiedInterface() throws Exception {
    _FunctionTypes._return_P1_E0<? extends Integer, ? super Boolean> ssdf = (Boolean b) -> 0;
  }
  public void accept_int(_FunctionTypes._return_P0_E0<? extends Integer> fun) {
  }
  public void accept_Integer(_FunctionTypes._return_P0_E0<? extends Integer> fun) {
  }
  public void accept_Number(_FunctionTypes._return_P0_E0<? extends Number> fun) {
  }
  public void accept_int_from_int(_FunctionTypes._return_P1_E0<? extends Integer, ? super Integer> fun) {
  }
  public void accept_int_from_Integer(_FunctionTypes._return_P1_E0<? extends Integer, ? super Integer> fun) {
  }
  public void accept_Integer_from_int(_FunctionTypes._return_P1_E0<? extends Integer, ? super Integer> fun) {
  }
  public void accept_Integer_from_Object(_FunctionTypes._return_P1_E0<? extends Integer, ? super Object> fun) {
  }
  public void accept_Number_from_String(_FunctionTypes._return_P1_E0<? extends Number, ? super String> fun) {
  }
}
