/* * 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.TypeElement; import javax.lang.model.util.Elements; import com.facebook.litho.annotations.OnCreateLayout; import com.facebook.litho.annotations.OnEvent; import com.facebook.litho.annotations.OnUpdateState; import com.facebook.litho.annotations.Param; import com.facebook.litho.annotations.Prop; import com.facebook.litho.annotations.State; import com.facebook.litho.annotations.TreeProp; import com.facebook.litho.specmodels.model.SpecModel; import com.facebook.litho.specmodels.processor.LayoutSpecModelFactory; import com.google.testing.compile.CompilationRule; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import static org.assertj.core.api.Java6Assertions.assertThat; /** * Tests {@link StateGenerator} */ public class StateGeneratorTest { @Rule public CompilationRule mCompilationRule = new CompilationRule(); private static class TestWithStateSpec<T extends CharSequence> { @OnCreateLayout public void onCreateLayout( @Prop boolean arg0, @State int arg1, @Param Object arg2, @TreeProp long arg3, @State(canUpdateLazily = true) boolean arg4) { } @OnEvent(Object.class) public void testEventMethod2( @Prop boolean arg0, @State int arg1) {} @OnUpdateState void updateCurrentState() { } } private static class TestWithoutStateSpec<T extends CharSequence> { @OnCreateLayout public void onCreateLayout() { } } private SpecModel mSpecModelWithState; private SpecModel mSpecModelWithoutState; @Before public void setUp() { Elements elements = mCompilationRule.getElements(); TypeElement typeElementWithState = elements.getTypeElement(TestWithStateSpec.class.getCanonicalName()); mSpecModelWithState = LayoutSpecModelFactory.create(elements, typeElementWithState, null); TypeElement typeElementWithoutState = elements.getTypeElement(TestWithoutStateSpec.class.getCanonicalName()); mSpecModelWithoutState = LayoutSpecModelFactory.create(elements, typeElementWithoutState, null); } @Test public void testGenerateHasState() { TypeSpecDataHolder dataHolder = StateGenerator.generateHasState(mSpecModelWithState); assertThat(dataHolder.getMethodSpecs()).hasSize(1); assertThat(dataHolder.getMethodSpecs().get(0).toString()) .isEqualTo( "@java.lang.Override\n" + "protected boolean hasState() {\n" + " return true;\n" + "}\n"); } @Test public void testDoNotGenerateState() { TypeSpecDataHolder dataHolder = StateGenerator.generateHasState(mSpecModelWithoutState); assertThat(dataHolder.getMethodSpecs()).isEmpty(); } @Test public void testGenerateTransferState() { TypeSpecDataHolder dataHolder = StateGenerator.generateTransferState(mSpecModelWithState); assertThat(dataHolder.getMethodSpecs()).hasSize(1); assertThat(dataHolder.getMethodSpecs().get(0).toString()) .isEqualTo( "@java.lang.Override\n" + "protected void transferState(com.facebook.litho.ComponentContext context,\n" + " com.facebook.litho.ComponentLifecycle.StateContainer prevStateContainer,\n" + " com.facebook.litho.Component component) {\n" + " TestWithStateStateContainerImpl prevStateContainerImpl = (TestWithStateStateContainerImpl) prevStateContainer;\n" + " TestWithStateImpl componentImpl = (TestWithStateImpl) component;\n" + " componentImpl.mStateContainerImpl.arg1 = prevStateContainerImpl.arg1;\n" + " componentImpl.mStateContainerImpl.arg4 = prevStateContainerImpl.arg4;\n" + "}\n"); } @Test public void testDoNotGenerateTransferState() { TypeSpecDataHolder dataHolder = StateGenerator.generateTransferState(mSpecModelWithoutState); assertThat(dataHolder.getMethodSpecs()).isEmpty(); } @Test public void testGenerateOnStateUpdateMethods() { TypeSpecDataHolder dataHolder = StateGenerator.generateOnStateUpdateMethods(mSpecModelWithState); assertThat(dataHolder.getMethodSpecs()).hasSize(2); assertThat(dataHolder.getMethodSpecs().get(0).toString()) .isEqualTo( "protected static void updateCurrentStateAsync(com.facebook.litho.ComponentContext c) {\n" + " com.facebook.litho.Component _component = c.getComponentScope();\n" + " if (_component == null) {\n" + " return;\n" + " }\n" + " TestWithState.UpdateCurrentStateStateUpdate _stateUpdate = ((TestWithState.TestWithStateImpl) _component).createUpdateCurrentStateStateUpdate();\n" + " c.updateStateAsync(_stateUpdate);\n" + "}\n"); assertThat(dataHolder.getMethodSpecs().get(1).toString()) .isEqualTo( "protected static void updateCurrentState(com.facebook.litho.ComponentContext c) {\n" + " com.facebook.litho.Component _component = c.getComponentScope();\n" + " if (_component == null) {\n" + " return;\n" + " }\n" + " TestWithState.UpdateCurrentStateStateUpdate _stateUpdate = ((TestWithState.TestWithStateImpl) _component).createUpdateCurrentStateStateUpdate();\n" + " c.updateState(_stateUpdate);\n" + "}\n"); } @Test public void testGenerateStateUpdateClasses() { TypeSpecDataHolder dataHolder = StateGenerator.generateStateUpdateClasses(mSpecModelWithState); assertThat(dataHolder.getTypeSpecs()).hasSize(1); assertThat(dataHolder.getTypeSpecs().get(0).toString()) .isEqualTo( "private static class UpdateCurrentStateStateUpdate implements com.facebook.litho.ComponentLifecycle.StateUpdate {\n" + " UpdateCurrentStateStateUpdate() {\n" + " }\n" + "\n" + " public void updateState(com.facebook.litho.ComponentLifecycle.StateContainer stateContainer,\n" + " com.facebook.litho.Component newComponent) {\n" + " TestWithStateStateContainerImpl stateContainerImpl = (TestWithStateStateContainerImpl) stateContainer;\n" + " TestWithStateImpl newComponentStateUpdate = (TestWithStateImpl) newComponent;\n" + " TestWithStateSpec.updateCurrentState();\n" + " }\n" + "\n" + " public boolean isLazyStateUpdate() {\n" + " return false;\n" + " }\n" + "}\n"); } @Test public void testGenerateLazyStateUpdateMethods() { TypeSpecDataHolder dataHolder = StateGenerator.generateLazyStateUpdateMethods(mSpecModelWithState); assertThat(dataHolder.getMethodSpecs()).hasSize(1); assertThat(dataHolder.getMethodSpecs().get(0).toString()) .isEqualTo( "protected static void lazyUpdateArg4(com.facebook.litho.ComponentContext c,\n" + " final boolean lazyUpdateValue) {\n" + " com.facebook.litho.Component _component = c.getComponentScope();\n" + " if (_component == null) {\n" + " return;\n" + " }\n" + " com.facebook.litho.ComponentLifecycle.StateUpdate _stateUpdate = new com.facebook.litho.ComponentLifecycle.StateUpdate() {\n" + " public void updateState(com.facebook.litho.ComponentLifecycle.StateContainer stateContainer,\n" + " com.facebook.litho.Component newComponent) {\n" + " TestWithState.TestWithStateImpl newComponentStateUpdate = (TestWithState.TestWithStateImpl) newComponent;\n" + " com.facebook.litho.StateValue<java.lang.Boolean> arg4 = new com.facebook.litho.StateValue<java.lang.Boolean>();\n" + " arg4.set(lazyUpdateValue);\n" + " newComponentStateUpdate.mStateContainerImpl.arg4 = arg4.get();\n" + " }\n" + "\n" + " public boolean isLazyStateUpdate() {\n" + " return true;\n" + " }\n" + " };\n" + " c.updateStateLazy(_stateUpdate);\n" + "}\n"); } }