content: package io.activej.specializer;
  
  import org.junit.Assert;
  import org.junit.Test;
  
  import java.util.function.IntUnaryOperator;
  
  public class SpecializerTest {
  	public static final class IntUnaryOperatorConst implements IntUnaryOperator {
  		private final int value;
  
  		public IntUnaryOperatorConst(int value) {this.value = value;}
  
  		@Override
  		public int applyAsInt(int operand) {
  			return value;
  		}
  	}
  
  	public static final class IntUnaryOperatorIdentity implements IntUnaryOperator {
  		@Override
  		public int applyAsInt(int operand) {
  			return operand;
  		}
  	}
  
  	public static final class IntUnaryOperatorSum implements IntUnaryOperator {
  		private final IntUnaryOperator delegate1;
  		private final IntUnaryOperator delegate2;
  
  		public IntUnaryOperatorSum(IntUnaryOperator delegate1, IntUnaryOperator delegate2) {
  			this.delegate1 = delegate1;
  			this.delegate2 = delegate2;
  		}
  
  		@Override
  		public int applyAsInt(int operand) {
  			return delegate1.applyAsInt(operand) + delegate2.applyAsInt(operand);
  		}
  	}
  
  	public static final class IntUnaryOperatorProduct implements IntUnaryOperator {
  		private final IntUnaryOperator delegate1;
  		private final IntUnaryOperator delegate2;
  
  		public IntUnaryOperatorProduct(IntUnaryOperator delegate1, IntUnaryOperator delegate2) {
  			this.delegate1 = delegate1;
  			this.delegate2 = delegate2;
  		}
  
  		@Override
  		public int applyAsInt(int operand) {
  			return delegate1.applyAsInt(operand) * delegate2.applyAsInt(operand);
  		}
  	}
  
  	@Test
  	public void testIntUnaryOperator0() {
  		TestClass0 instance = new TestClass0(new TestClass0(1));
  
  		int expected = instance.apply(0);
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp").toAbsolutePath());
  		TestInterface specialized = specializer.specialize(instance);
  		Assert.assertEquals(expected, specialized.apply(0));
  	}
  
  	@Test
  	public void testIntUnaryOperator1() {
  		IntUnaryOperator instance =
  			new IntUnaryOperatorProduct(
  				new IntUnaryOperatorSum(
  					new IntUnaryOperatorSum(
  						new IntUnaryOperatorIdentity(),
  						new IntUnaryOperatorConst(5)),
  					new IntUnaryOperatorConst(-5)),
  				new IntUnaryOperatorConst(-1));
  		int expected = instance.applyAsInt(5);
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp").toAbsolutePath());
  		IntUnaryOperator specialized = specializer.specialize(instance);
  		Assert.assertEquals(expected, specialized.applyAsInt(5));
  	}
  
  	@Test
  	public void name() {
  		TestClass1 specializableClass = new TestClass1(new TestClass2(), new TestClass1(null, null));
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp").toAbsolutePath());
  		TestInterface specialized = specializer.specialize(specializableClass);
  		int expected = specializableClass.apply(55);
  		Assert.assertEquals(expected, specialized.apply(55));
  	}
  
  	@Test
  	public void testIfElse() {
  		TestInterface ifElseTestClass = new IfElseTestClass(x -> x * 2);
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp"));
  		TestInterface specialized = specializer.specialize(ifElseTestClass);
  		Assert.assertEquals(6, specialized.apply(3));
  	}
  
  	@Test
  	public void testIfElse2() {
  		TestInterface ifElseTestClass = new IfElseTestClass2();
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp"));
  		TestInterface specialized = specializer.specialize(ifElseTestClass);
  		Assert.assertEquals(0, specialized.apply(3));
  	}
  
  	@Test
  	public void testIfElse3() {
  		TestInterface ifElseTestClass = new IfElseTestClass3();
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp"));
  		TestInterface specialized = specializer.specialize(ifElseTestClass);
  		Assert.assertEquals(0, specialized.apply(3));
  	}
  
  	@Test
  	public void testIfElse4() {
  		TestInterface ifElseTestClass = new IfElseTestClass4();
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp"));
  		TestInterface specialized = specializer.specialize(ifElseTestClass);
  		Assert.assertEquals(0, specialized.apply(3));
  	}
  
  	@Test
  	public void testIfElse5() {
  		TestInterface ifElseTestClass = new IfElseTestClass5();
  		Specializer specializer = Specializer.create();
  //				.withBytecodeSaveDir(Paths.get("tmp"));
  		TestInterface specialized = specializer.specialize(ifElseTestClass);
  		Assert.assertEquals(0, specialized.apply(3));
  	}
  
  	@Test
  	public void testMultipleFrames() {
  		TestInterface multipleFramesTestClass = new MultipleFramesTestClass();
  		Specializer specializer = Specializer.create();
  		TestInterface specialized = specializer.specialize(multipleFramesTestClass);
  		Assert.assertEquals(0, specialized.apply(3));
  	}
  
  	@Test
  	public void testStaticFields() {
  		TestInterface staticFieldTestClass = new StaticFieldTestClass();
  		Specializer specializer = Specializer.create();
  		TestInterface specialized = specializer.specialize(staticFieldTestClass);
  		Assert.assertEquals(staticFieldTestClass.apply(3), specialized.apply(3));
  	}
  
  	@Test
  	public void testStaticMethods() {
  		TestInterface staticMethodsTestClass = new StaticMethodTestClass();
  		Specializer specializer = Specializer.create();
  		TestInterface specialized = specializer.specialize(staticMethodsTestClass);
  		Assert.assertEquals(staticMethodsTestClass.apply(3), specialized.apply(3));
  	}
  }
  