/** * Assert that a given {@link Component} produces a layout that's not equivalent to {@link * ComponentContext#NULL_LAYOUT}. */ public ComponentAssert willRender() { Java6Assertions.assertThat(Component.willRender(mComponentContext, actual)) .overridingErrorMessage("Expected Component to not render to null, but it did.") .isTrue(); return this; }
/** * Assert that a given {@link Component} renders to null, i.e. its <code>onCreateLayout * </code> method resolves to a {@link ComponentContext#NULL_LAYOUT}. */ public ComponentAssert wontRender() { Java6Assertions.assertThat(Component.willRender(mComponentContext, actual)) .overridingErrorMessage("Expected Component to render to null, but it did not.") .isFalse(); return this; }
@OnCreateLayout static @Nullable Component onCreateLayout( final ComponentContext c, final @Prop(varArg = "component", optional = true) List<Component> components) { if (components == null) { return null; } for (int i = 0; i < components.size(); i++) { final Component component = components.get(i); if (Component.willRender(c, component)) { return component; } } return null; } }
/** * @return whether the given component will render because it returns non-null from its resolved * onCreateLayout, based on its current props and state. Returns true if the resolved layout * is non-null, otherwise false. * @deprecated Using willRender is regarded as an anti-pattern, since it will load all classes * into memory in order to potentially decide not to use any of them. */ @Deprecated public static boolean willRender(ComponentContext c, Component component) { if (component == null) { return false; } final ComponentContext scopedContext = component.getScopedContext(); if (scopedContext != null) { assertSameBaseContext(scopedContext, c); } if (component.mLayoutCreatedInWillRender != null) { return willRender(component.mLayoutCreatedInWillRender); } component.mLayoutCreatedInWillRender = Layout.create(c, component); return willRender(component.mLayoutCreatedInWillRender); }
@OnCreateLayout static @Nullable Component onCreateLayout( final ComponentContext c, final @Prop(varArg = "component", optional = true) List<ComponentCreator> components) { if (components == null) { return null; } for (int i = 0; i < components.size(); i++) { final Component component = components.get(i).create(); if (Component.willRender(c, component)) { return component; } } return null; } }
@Override protected Component onCreateLayout(final ComponentContext c) { Component.willRender(c, componentSpy); return Column.create(c).child(componentSpy).build(); } };
@Test public void testWillRenderTwiceDoesNotReCreateLayout() { ComponentContext c = new ComponentContext(application); final Component component = TestLayoutComponent.create(c, 0, 0, true, true, true, false).build(); Component.willRender(c, component); final InternalNode cachedLayout = component.getLayoutCreatedInWillRenderForTesting(); assertThat(cachedLayout).isNotNull(); assertThat(Component.willRender(c, component)).isTrue(); assertThat(component.getLayoutCreatedInWillRenderForTesting()).isEqualTo(cachedLayout); }
@Test public void testWillRenderLayoutsOnce() { ComponentContext c = new ComponentContext(application); final Component componentSpy = spy(TestLayoutComponent.create(c, 0, 0, true, true, true, false).build()); Component.willRender(c, componentSpy); final InternalNode cachedLayout = componentSpy.getLayoutCreatedInWillRenderForTesting(); assertThat(cachedLayout).isNotNull(); calculateLayoutState( c.getAndroidContext(), componentSpy, -1, makeSizeSpec(100, EXACTLY), makeSizeSpec(100, EXACTLY)); assertThat(componentSpy.getLayoutCreatedInWillRenderForTesting()).isNull(); verify(componentSpy, times(1)).updateInternalChildState(any(ComponentContext.class)); }
@Test public void testNewLayoutBuilderUsesWillRenderResult() { ComponentContext c = new ComponentContext(application); final Component component = TestLayoutComponent.create(c, 0, 0, true, true, true, false).build(); Component.willRender(c, component); final InternalNode cachedLayout = component.getLayoutCreatedInWillRenderForTesting(); assertThat(cachedLayout).isNotNull(); InternalNode result = c.newLayoutBuilder(component, 0, 0); assertThat(result).isEqualTo(cachedLayout); assertThat(component.getLayoutCreatedInWillRenderForTesting()).isNull(); }
@Test public void testResolveLayoutUsesWillRenderResult() { ComponentContext c = new ComponentContext(application); final Component component = TestLayoutComponent.create(c, 0, 0, true, true, true, false).build(); Component.willRender(c, component); final InternalNode cachedLayout = component.getLayoutCreatedInWillRenderForTesting(); assertThat(cachedLayout).isNotNull(); InternalNode result = c.resolveLayout(component); assertThat(result).isEqualTo(cachedLayout); assertThat(component.getLayoutCreatedInWillRenderForTesting()).isNull(); }
@Test public void testCreateLayoutUsesWillRenderResult() { ComponentContext c = new ComponentContext(application); final Component component = TestLayoutComponent.create(c, 0, 0, true, true, true, false).build(); Component.willRender(c, component); final InternalNode cachedLayout = component.getLayoutCreatedInWillRenderForTesting(); assertThat(cachedLayout).isNotNull(); InternalNode result = component.createLayout(c, false); assertThat(result).isEqualTo(cachedLayout); assertThat(component.getLayoutCreatedInWillRenderForTesting()).isNull(); }
@Test public void testWillRenderForComponentWithSizeSpecThrowsException() { mExpectedException.expect(IllegalArgumentException.class); mExpectedException.expectMessage("@OnCreateLayoutWithSizeSpec"); ComponentContext c = new ComponentContext(application); Component.willRender(c, Wrapper.create(c).delegate(mLayoutWithSizeSpec).build()); } }