@Override public void bind(@NonNull LithoView view, @NonNull EpoxyModel<?> previouslyBoundModel) { view.getComponentTree().setRoot(getComponent(view.getComponentContext())); }
@Override public void bind(@NonNull LithoView view, @NonNull List<Object> payloads) { if (payloads.isEmpty()) { bind(view); } else { view.getComponentTree().setRoot(getComponent(view.getComponentContext())); } }
/** * Change the root component synchronously. */ public void setComponent(Component component) { if (mComponentTree == null) { setComponentTree(ComponentTree.create(getComponentContext(), component).build()); } else { mComponentTree.setRoot(component); } }
@Test public void testLifecycle() { mLithoView.onAttachedToWindow(); measureAndLayout(mLithoView); assertThat(mComponent.getCurrentStep()).isEqualTo(LifecycleStep.ON_BIND); mLithoView.onDetachedFromWindow(); assertThat(mComponent.getCurrentStep()).isEqualTo(LifecycleStep.ON_UNBIND); mLithoView.onAttachedToWindow(); assertThat(mComponent.getCurrentStep()).isEqualTo(LifecycleStep.ON_BIND); mComponentTree.setRoot(LifecycleMethodsComponent.create(20)); measureAndLayout(mLithoView); assertThat(mComponent.getCurrentStep()).isEqualTo(LifecycleStep.ON_UNMOUNT); mComponentTree.setRoot(mComponent); measureAndLayout(mLithoView); assertThat(mComponent.getCurrentStep()).isEqualTo(LifecycleStep.ON_BIND); mLithoView.onDetachedFromWindow(); mComponentTree.setRoot(mComponent); measureAndLayout(mLithoView); assertThat(mComponent.getCurrentStep()).isEqualTo(LifecycleStep.ON_UNBIND); }
@Test public void testClearUnusedEntries() { Component component = mock(Component.class); ComponentTree componentTree = ComponentTree.create(mContext, component).build(); EventHandlersController eventHandlersController = componentTree.getEventHandlersController(); EventHandler eventHandler1 = mContext.newEventHandler(1); when(component.getGlobalKey()).thenReturn("component1"); componentTree.recordEventHandler(component, eventHandler1); eventHandlersController.bindEventHandlers(mContext, component, component.getGlobalKey()); eventHandlersController.clearUnusedEventHandlers(); assertThat(eventHandlersController.getEventHandlers().size()).isEqualTo(1); when(component.getGlobalKey()).thenReturn("component2"); componentTree.setRoot(component); componentTree.recordEventHandler(component, eventHandler1); eventHandlersController.bindEventHandlers(mContext, component, component.getGlobalKey()); eventHandlersController.clearUnusedEventHandlers(); assertThat(eventHandlersController.getEventHandlers().size()).isEqualTo(1); } }
@Test public void testSetRootAfterRelease() { ComponentTree componentTree = ComponentTree.create(mContext, mComponent).build(); componentTree.release(); // Verify we don't crash componentTree.setRoot(TestDrawableComponent.create(mContext).build()); }
.setRoot( new InlineLayoutSpec() { @Override
@Test public void testMountUnmountWithNewOrientation() { mContext.getResources().getConfiguration().orientation = ORIENTATION_PORTRAIT; final TestComponent firstComponent = create(mContext).build(); final LithoView lithoView = mountComponent(mContext, Column.create(mContext).child(firstComponent).build()); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); mContext.getResources().getConfiguration().orientation = ORIENTATION_LANDSCAPE; final TestComponent secondComponent = create(mContext).build(); lithoView.getComponentTree().setRoot(Column.create(mContext).child(secondComponent).build()); assertThat(secondComponent.wasOnMountCalled()).isTrue(); assertThat(secondComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnbindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isTrue(); }
.setRoot( new InlineLayoutSpec() { @Override
@Test public void testMountUnmountWithNoShouldUpdateAndDifferentMeasures() { final TestComponent firstComponent = create(mContext) .build(); final LithoView lithoView = mountComponent( new LithoView(mContext), ComponentTree.create(mContext, Column.create(mContext).child(firstComponent).build()) .build(), makeMeasureSpec(100, AT_MOST), makeMeasureSpec(100, AT_MOST)); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .build(); lithoView .getComponentTree() .setRoot(Column.create(mContext).child(secondComponent).widthPx(10).heightPx(10).build()); assertThat(lithoView.isLayoutRequested()).isTrue(); assertThat(secondComponent.wasOnMountCalled()).isFalse(); assertThat(secondComponent.wasOnBindCalled()).isFalse(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); }
.setRoot( new InlineLayoutSpec() { @Override
@Test public void testMountUnmountWithNoShouldUpdate() { final TestComponent firstComponent = create(mContext) .build(); final LithoView lithoView = mountComponent(mContext, Column.create(mContext).child(firstComponent).build()); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .build(); lithoView.getComponentTree().setRoot(Column.create(mContext).child(secondComponent).build()); assertThat(secondComponent.wasOnMountCalled()).isFalse(); assertThat(secondComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); }
@Test public void testMountUnmountWithShouldUpdate() { final TestComponent firstComponent = create(mContext) .unique() .build(); final LithoView lithoView = mountComponent(mContext, Column.create(mContext).child(firstComponent).build()); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .unique() .build(); lithoView.getComponentTree().setRoot(Column.create(mContext).child(secondComponent).build()); assertThat(secondComponent.wasOnMountCalled()).isTrue(); assertThat(secondComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isTrue(); }
@Test public void testMountUnmountWithSkipShouldUpdateAndRemount() { final TestComponent firstComponent = create(mContext) .color(BLACK) .build(); final LithoView lithoView = mountComponent(mContext, Column.create(mContext).child(firstComponent).build()); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .color(WHITE) .build(); lithoView.getComponentTree().setRoot(Column.create(mContext).child(secondComponent).build()); assertThat(secondComponent.wasOnMountCalled()).isTrue(); assertThat(secondComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isTrue(); }
@Test public void testRebindWithNoShouldUpdateAndSameMeasures() { final TestComponent firstComponent = create(mContext) .build(); final LithoView lithoView = mountComponent( new LithoView(mContext), ComponentTree.create(mContext, Column.create(mContext).child(firstComponent).build()) .build(), makeMeasureSpec(100, EXACTLY), makeMeasureSpec(100, EXACTLY)); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .build(); lithoView .getComponentTree() .setRoot(Column.create(mContext).child(secondComponent).widthPx(10).heightPx(10).build()); assertThat(lithoView.isLayoutRequested()).isFalse(); assertThat(secondComponent.wasOnMountCalled()).isFalse(); assertThat(secondComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); }
@Test public void testMountUnmountWithSkipShouldUpdate() { final TestComponent firstComponent = create(mContext) .color(BLACK) .build(); final LithoView lithoView = mountComponent(mContext, Column.create(mContext).child(firstComponent).build()); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .color(BLACK) .build(); lithoView.getComponentTree().setRoot(Column.create(mContext).child(secondComponent).build()); assertThat(secondComponent.wasOnMountCalled()).isFalse(); assertThat(secondComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); }
@Test public void testMountUnmountDoesNotSkipShouldUpdateAndRemount() { final TestComponent firstComponent = create(mContext) .unique() .build(); final LithoView firstLithoView = mountComponent(mContext, Column.create(mContext).child(firstComponent).build()); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .unique() .build(); final ComponentTree secondTree = ComponentTree.create(mContext, Column.create(mContext).child(secondComponent).build()) .build(); secondTree.setSizeSpec(100, 100); final TestComponent thirdComponent = spy(create(mContext).build()); doReturn(thirdComponent).when(thirdComponent).makeShallowCopy(); secondTree.setRoot(Column.create(mContext).child(thirdComponent).build()); mountComponent(firstLithoView, secondTree); verify(thirdComponent).makeShallowCopy(); assertThat(thirdComponent.wasOnMountCalled()).isTrue(); assertThat(thirdComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isTrue(); }
@Test public void testRemountsWithNewInputOnSameLayout() { final LithoView lithoView = mountComponent( mContext, create(mContext) .color(BLACK) .build()); shadowOf(lithoView).callOnAttachedToWindow(); assertThat(lithoView.getDrawables()).hasSize(1); assertThat(((ColorDrawable) lithoView.getDrawables().get(0)).getColor()).isEqualTo(BLACK); lithoView.getComponentTree().setRoot( create(mContext) .color(YELLOW) .build()); assertThat(lithoView.getDrawables()).hasSize(1); assertThat(((ColorDrawable) lithoView.getDrawables().get(0)).getColor()).isEqualTo(YELLOW); } }
@Test public void testMountUnmountWithNoShouldUpdateAndSameMeasures() { final TestComponent firstComponent = create(mContext, 0, 0, true, true, true, false, false, true) .color(Color.GRAY) .build(); final LithoView lithoView = mountComponent( new LithoView(mContext), ComponentTree.create(mContext, Column.create(mContext).child(firstComponent).build()) .build(), makeMeasureSpec(100, EXACTLY), makeMeasureSpec(100, EXACTLY)); assertThat(firstComponent.wasOnMountCalled()).isTrue(); assertThat(firstComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isFalse(); final TestComponent secondComponent = create(mContext) .color(Color.RED) .build(); lithoView .getComponentTree() .setRoot(Column.create(mContext).child(secondComponent).widthPx(10).heightPx(10).build()); assertThat(lithoView.isLayoutRequested()).isFalse(); assertThat(secondComponent.wasOnMountCalled()).isTrue(); assertThat(secondComponent.wasOnBindCalled()).isTrue(); assertThat(firstComponent.wasOnUnmountCalled()).isTrue(); }
@Test public void testSetInput() { Component component = TestLayoutComponent.create(mContext) .build(); ComponentTree componentTree = ComponentTree.create(mContext, component) .build(); componentTree.setRoot(mComponent); creationCommonChecks(componentTree); Assert.assertNull(Whitebox.getInternalState(componentTree, "mMainThreadLayoutState")); Assert.assertNull(Whitebox.getInternalState(componentTree, "mBackgroundLayoutState")); componentTree.setSizeSpec(mWidthSpec, mHeightSpec); // Since this happens post creation, it's not in general safe to update the main thread layout // state synchronously, so the result should be in the background layout state postSizeSpecChecks(componentTree, "mBackgroundLayoutState"); }