// Path: generator/src/main/java/com/truecaller/androidactors/ActorInterfaceDescription.java
// interface Method {
//     @NotNull
//     String getName();
// 
//     @NotNull
//     TypeMirror getType();
// 
//     @Nullable
//     TypeMirror getPromisedType();
// 
//     Iterable<? extends Argument> arguments();
// 
//     interface Argument {
//         @NotNull
//         String getName();
// 
//         @NotNull
//         TypeMirror getType();
// 
//         @NotNull
//         List<? extends AnnotationMirror> getAnnotations();
// 
//         int getSecureLevel();
//     }
// }
// 
// Path: generator/src/test/java/com/truecaller/androidactors/cases/ActorContainerClass.java
// public class ActorContainerClass {
//     public interface NestedActor {
//         void testMethod();
//     }
// }
// 
// Path: generator/src/test/java/com/truecaller/androidactors/cases/ActorContainerInterface.java
// public interface ActorContainerInterface {
//     interface NestedActor {
//         void testMethod();
//     }
// }
// 
// Path: generator/src/test/java/com/truecaller/androidactors/cases/SimpleActor.java
// public interface SimpleActor {
//     void save(long key, @Nullable String value);
// 
//     @NonNull
//     Promise<String> get(long key);
// }


import androidx.annotation.NonNull;
import com.google.common.collect.Iterables;
import com.google.testing.compile.CompilationRule;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.truecaller.androidactors.ActorInterfaceDescription.Method;
import com.truecaller.androidactors.cases.ActorContainerClass;
import com.truecaller.androidactors.cases.ActorContainerInterface;
import com.truecaller.androidactors.cases.SimpleActor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleElementVisitor6;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
    }

    @Test
    public void getProxyPackage_equals_SimpleActor() {
        setTypeElement(SimpleActor.class);

        ActorInterfaceGeneratedImpl generated = new ActorInterfaceGeneratedImpl(mDescription);
        Assert.assertEquals("com.truecaller.androidactors.cases", generated.getProxyPackage());
    }

    @Test
    public void getProxyName_equals_SimpleActor() {
        setTypeElement(SimpleActor.class);

        ActorInterfaceGeneratedImpl generated = new ActorInterfaceGeneratedImpl(mDescription);
        Assert.assertEquals("SimpleActor$Proxy", generated.getProxyName());
    }

    @Test
    public void generate_validMethods_SimpleActor() {
        setTypeElement(SimpleActor.class);

        List<Method> methods = new ArrayList<>();
        methods.add(method("save",
                argument("key", TypeKind.LONG), argument("value", String.class.getCanonicalName(), true)));
        methods.add(method("get", String.class.getCanonicalName(),
                argument("key", TypeKind.LONG)));
        Mockito.doReturn(methods).when(mDescription).methods();

        ActorInterfaceGeneratedImpl generated = new ActorInterfaceGeneratedImpl(mDescription);
// Path: generator/src/main/java/com/truecaller/androidactors/ActorInterfaceDescription.java
// interface Method {
//     @NotNull
//     String getName();
// 
//     @NotNull
//     TypeMirror getType();
// 
//     @Nullable
//     TypeMirror getPromisedType();
// 
//     Iterable<? extends Argument> arguments();
// 
//     interface Argument {
//         @NotNull
//         String getName();
// 
//         @NotNull
//         TypeMirror getType();
// 
//         @NotNull
//         List<? extends AnnotationMirror> getAnnotations();
// 
//         int getSecureLevel();
//     }
// }
// 
// Path: generator/src/test/java/com/truecaller/androidactors/cases/ActorContainerClass.java
// public class ActorContainerClass {
//     public interface NestedActor {
//         void testMethod();
//     }
// }
// 
// Path: generator/src/test/java/com/truecaller/androidactors/cases/ActorContainerInterface.java
// public interface ActorContainerInterface {
//     interface NestedActor {
//         void testMethod();
//     }
// }
// 
// Path: generator/src/test/java/com/truecaller/androidactors/cases/SimpleActor.java
// public interface SimpleActor {
//     void save(long key, @Nullable String value);
// 
//     @NonNull
//     Promise<String> get(long key);
// }


// Path: generator/src/test/java/com/truecaller/androidactors/ActorInterfaceGeneratedImplTest.java
import androidx.annotation.NonNull;
import com.google.common.collect.Iterables;
import com.google.testing.compile.CompilationRule;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.truecaller.androidactors.ActorInterfaceDescription.Method;
import com.truecaller.androidactors.cases.ActorContainerClass;
import com.truecaller.androidactors.cases.ActorContainerInterface;
import com.truecaller.androidactors.cases.SimpleActor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleElementVisitor6;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

    }

    @Test
    public void getProxyPackage_equals_SimpleActor() {
        setTypeElement(SimpleActor.class);

        ActorInterfaceGeneratedImpl generated = new ActorInterfaceGeneratedImpl(mDescription);
        Assert.assertEquals("com.truecaller.androidactors.cases", generated.getProxyPackage());
    }

    @Test
    public void getProxyName_equals_SimpleActor() {
        setTypeElement(SimpleActor.class);

        ActorInterfaceGeneratedImpl generated = new ActorInterfaceGeneratedImpl(mDescription);
        Assert.assertEquals("SimpleActor$Proxy", generated.getProxyName());
    }

    @Test
    public void generate_validMethods_SimpleActor() {
        setTypeElement(SimpleActor.class);

        List<Method> methods = new ArrayList<>();
        methods.add(method("save",
                argument("key", TypeKind.LONG), argument("value", String.class.getCanonicalName(), true)));
        methods.add(method("get", String.class.getCanonicalName(),
                argument("key", TypeKind.LONG)));
        Mockito.doReturn(methods).when(mDescription).methods();

        ActorInterfaceGeneratedImpl generated = new ActorInterfaceGeneratedImpl(mDescription);
        JavaFile file = generated.generate(mNamesProvider);