/*
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.litho.specmodels.generator;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import com.facebook.litho.annotations.FromEvent;
import com.facebook.litho.annotations.OnEvent;
import com.facebook.litho.annotations.Param;
import com.facebook.litho.annotations.Prop;
import com.facebook.litho.annotations.PropDefault;
import com.facebook.litho.annotations.State;
import com.facebook.litho.specmodels.internal.ImmutableList;
import com.facebook.litho.specmodels.model.ClassNames;
import com.facebook.litho.specmodels.model.EventDeclarationModel;
import com.facebook.litho.specmodels.model.SpecModel;
import com.facebook.litho.specmodels.processor.LayoutSpecModelFactory;
import com.google.testing.compile.CompilationRule;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.TypeName;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Tests {@link EventGenerator}
*/
public class EventGeneratorTest {
@Rule public CompilationRule mCompilationRule = new CompilationRule();
static class TestSpec<T extends CharSequence> {
@PropDefault protected static boolean arg0 = true;
@OnEvent(Object.class)
public void testEventMethod1(
@Prop boolean arg0,
@State int arg1,
@Param Object arg2,
@Param T arg3,
@FromEvent long arg4) {}
@OnEvent(Object.class)
public void testEventMethod2(
@Prop boolean arg0,
@State int arg1) {}
}
private SpecModel mSpecModel;
private final SpecModel mMockSpecModel = mock(SpecModel.class);
@Before
public void setUp() {
Elements elements = mCompilationRule.getElements();
TypeElement typeElement = elements.getTypeElement(TestSpec.class.getCanonicalName());
mSpecModel = LayoutSpecModelFactory.create(elements, typeElement, null);
EventDeclarationModel eventDeclarationModel = new EventDeclarationModel(
ClassName.OBJECT,
ClassName.OBJECT,
ImmutableList.of(
new EventDeclarationModel.FieldModel(
FieldSpec.builder(TypeName.INT, "field1", Modifier.PUBLIC).build(),
new Object()),
new EventDeclarationModel.FieldModel(
FieldSpec.builder(TypeName.INT, "field2", Modifier.PUBLIC).build(),
new Object())),
new Object());
when(mMockSpecModel.getEventDeclarations())
.thenReturn(ImmutableList.of(eventDeclarationModel));
when(mMockSpecModel.getContextClass()).thenReturn(ClassNames.COMPONENT_CONTEXT);
when(mMockSpecModel.getComponentName()).thenReturn("Test");
}
@Test
public void testGenerateEventMethods() {
TypeSpecDataHolder dataHolder = EventGenerator.generateEventMethods(mSpecModel);
assertThat(dataHolder.getMethodSpecs()).hasSize(2);
assertThat(dataHolder.getMethodSpecs().get(0).toString())
.isEqualTo(
"private void testEventMethod1(com.facebook.litho.HasEventDispatcher _abstractImpl,\n" +
" java.lang.Object arg2, T arg3) {\n" +
" TestImpl _impl = (TestImpl) _abstractImpl;\n" +
" TestSpec.testEventMethod1(\n" +
" (boolean) _impl.arg0,\n" +
" (int) _impl.mStateContainerImpl.arg1,\n" +
" arg2,\n" +
" arg3,\n" +
" (long) _impl.arg4);\n" +
"}\n");
assertThat(dataHolder.getMethodSpecs().get(1).toString())
.isEqualTo(
"private void testEventMethod2(com.facebook.litho.HasEventDispatcher _abstractImpl) {\n" +
" TestImpl _impl = (TestImpl) _abstractImpl;\n" +
" TestSpec.testEventMethod2(\n" +
" (boolean) _impl.arg0,\n" +
" (int) _impl.mStateContainerImpl.arg1);\n" +
"}\n");
}
@Test
public void testGenerateEventHandlerFactories() {
TypeSpecDataHolder dataHolder = EventGenerator.generateEventHandlerFactories(mSpecModel);
assertThat(dataHolder.getMethodSpecs()).hasSize(4);
assertThat(dataHolder.getMethodSpecs().get(0).toString())
.isEqualTo(
"public static <T extends java.lang.CharSequence> com.facebook.litho.EventHandler<java.lang.Object> testEventMethod1(com.facebook.litho.ComponentContext c,\n" +
" java.lang.Object arg2, T arg3) {\n" +
" return newEventHandler(c, -1400079064, new Object[] {\n" +
" c,\n" +
" arg2,\n" +
" arg3,\n" +
" });\n" +
"}\n");
assertThat(dataHolder.getMethodSpecs().get(1).toString())
.isEqualTo(
"public static <T extends java.lang.CharSequence> com.facebook.litho.EventHandler<java.lang.Object> testEventMethod1(com.facebook.litho.Component c,\n" +
" java.lang.Object arg2, T arg3) {\n" +
" return newEventHandler(c, -1400079064, new Object[] {\n" +
" c,\n" +
" arg2,\n" +
" arg3,\n" +
" });\n" +
"}\n");
assertThat(dataHolder.getMethodSpecs().get(2).toString())
.isEqualTo(
"public static com.facebook.litho.EventHandler<java.lang.Object> testEventMethod2(com.facebook.litho.ComponentContext c) {\n" +
" return newEventHandler(c, -1400079063, new Object[] {\n" +
" c,\n" +
" });\n" +
"}\n");
assertThat(dataHolder.getMethodSpecs().get(3).toString())
.isEqualTo(
"public static com.facebook.litho.EventHandler<java.lang.Object> testEventMethod2(com.facebook.litho.Component c) {\n" +
" return newEventHandler(c, -1400079063, new Object[] {\n" +
" c,\n" +
" });\n" +
"}\n");
}
@Test
public void testGenerateDispatchOnEvent() {
assertThat(EventGenerator.generateDispatchOnEvent(mSpecModel).toString())
.isEqualTo(
"@java.lang.Override\n" +
"public java.lang.Object dispatchOnEvent(final com.facebook.litho.EventHandler eventHandler,\n" +
" final java.lang.Object eventState) {\n" +
" int id = eventHandler.id;\n" +
" switch(id) {\n" +
" case -1400079064: {\n" +
" java.lang.Object _event = (java.lang.Object) eventState;\n" +
" testEventMethod1(\n" +
" eventHandler.mHasEventDispatcher,\n" +
" (java.lang.Object) eventHandler.params[0],\n" +
" (T) eventHandler.params[1]);\n" +
" return null;\n" +
" }\n" +
" case -1400079063: {\n" +
" java.lang.Object _event = (java.lang.Object) eventState;\n" +
" testEventMethod2(\n" +
" eventHandler.mHasEventDispatcher);\n" +
" return null;\n" +
" }\n" +
" default:\n" +
" return null;\n" +
" }\n" +
"}\n");
}
@Test
public void testGetEventHandlerMethods() {
TypeSpecDataHolder dataHolder = EventGenerator.generateGetEventHandlerMethods(mMockSpecModel);
assertThat(dataHolder.getMethodSpecs()).hasSize(1);
assertThat(dataHolder.getMethodSpecs().get(0).toString())
.isEqualTo(
"public static com.facebook.litho.EventHandler getObjectHandler(com.facebook.litho.ComponentContext context) {\n" +
" if (context.getComponentScope() == null) {\n" +
" return null;\n" +
" }\n" +
" return ((Test.TestImpl) context.getComponentScope()).objectHandler;\n" +
"}\n");
}
@Test
public void testGenerateEventDispatchers() {
TypeSpecDataHolder dataHolder = EventGenerator.generateEventDispatchers(mMockSpecModel);
assertThat(dataHolder.getMethodSpecs()).hasSize(1);
assertThat(dataHolder.getMethodSpecs().get(0).toString())
.isEqualTo(
"static java.lang.Object dispatchObject(com.facebook.litho.EventHandler _eventHandler, int field1,\n" +
" int field2) {\n" +
" java.lang.Object _eventState = new java.lang.Object();\n" +
" _eventState.field1 = field1;\n" +
" _eventState.field2 = field2;\n" +
" com.facebook.litho.EventDispatcher _lifecycle = _eventHandler.mHasEventDispatcher.getEventDispatcher();\n" +
" return (java.lang.Object) _lifecycle.dispatchOnEvent(_eventHandler, _eventState);\n" +
"}\n");
}
}