<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook.litho;

import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.facebook.litho.LayoutOutput.getLayoutOutput;
import static com.facebook.litho.testing.TestDrawableComponent.create;
import static com.facebook.litho.testing.helper.ComponentTestHelper.mountComponent;
import static org.assertj.core.api.Java6Assertions.assertThat;

import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.litho.config.TempComponentsConfigurations;
import com.facebook.litho.drawable.ComparableDrawable;
import com.facebook.litho.testing.TestComponent;
import com.facebook.litho.testing.TestDrawableComponent;
import com.facebook.litho.testing.TestViewComponent;
import com.facebook.litho.testing.Whitebox;
import com.facebook.litho.testing.helper.ComponentTestHelper;
import com.facebook.litho.testing.testrunner.LithoTestRunner;
import com.facebook.litho.widget.EditText;
import com.facebook.litho.widget.Text;
import com.facebook.rendercore.MountDelegateTarget;
import com.facebook.rendercore.MountItem;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(LithoTestRunner.class)
public class MountStateRemountTest {
  private ComponentContext mContext;

  @Before
  public void setup() {
    TempComponentsConfigurations.setShouldDisableDrawableOutputs(true);
    mContext = new ComponentContext(getApplicationContext());
  }

  @Test
  public void testMountItemsHaveMountData() {
    final TestComponent component1 = create(mContext).build();
    final TestComponent component2 = create(mContext).build();

    final LithoView lithoView =
        mountComponent(
            mContext, Column.create(mContext).child(component1).child(component2).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();

    final MountDelegateTarget mountDelegateTarget = lithoView.getMountDelegateTarget();

    for (int i = 0; i < mountDelegateTarget.getMountItemCount(); i++) {
      MountItem item = mountDelegateTarget.getMountItemAt(i);
      assertThat(item.getMountData()).isOfAnyClassIn(LithoMountData.class);
    }
  }

  @Test
  public void testRemountSameLayoutState() {
    final TestComponent component1 = create(mContext).build();
    final TestComponent component2 = create(mContext).build();
    final TestComponent component3 = create(mContext).build();
    final TestComponent component4 = create(mContext).build();

    final LithoView lithoView =
        mountComponent(
            mContext, Column.create(mContext).child(component1).child(component2).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();

    mountComponent(
        mContext, lithoView, Column.create(mContext).child(component3).child(component4).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();
    assertThat(component3.isMounted()).isFalse();
    assertThat(component4.isMounted()).isFalse();

    final MountDelegateTarget mountDelegateTarget = lithoView.getMountDelegateTarget();

    final List<Component> components = new ArrayList<>();
    for (int i = 0; i < mountDelegateTarget.getMountItemCount(); i++) {
      components.add(getLayoutOutput(mountDelegateTarget.getMountItemAt(i)).getComponent());
    }

    assertThat(containsRef(components, component1)).isFalse();
    assertThat(containsRef(components, component2)).isFalse();
    assertThat(containsRef(components, component3)).isTrue();
    assertThat(containsRef(components, component4)).isTrue();
  }

  /**
   * There was a crash when mounting a drawing in place of a view. This test is here to make sure
   * this does not regress. To reproduce this crash the pools needed to be in a specific state as
   * view layout outputs and mount items were being re-used for drawables.
   */
  @Test
  public void testRemountDifferentMountType() throws IllegalAccessException, NoSuchFieldException {
    final LithoView lithoView =
        ComponentTestHelper.mountComponent(mContext, TestViewComponent.create(mContext).build());

    ComponentTestHelper.mountComponent(
        mContext, lithoView, TestDrawableComponent.create(mContext).build());
  }

  @Test
  public void testRemountNewLayoutState() {
    final TestComponent component1 = create(mContext).color(Color.RED).build();
    final TestComponent component2 = create(mContext).color(Color.BLUE).build();
    final TestComponent component3 = create(mContext).color(Color.GREEN).build();
    final TestComponent component4 = create(mContext).color(Color.YELLOW).build();

    final LithoView lithoView =
        mountComponent(
            mContext, Column.create(mContext).child(component1).child(component2).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();

    mountComponent(<commit_msg>Changed use of componentTestHelper to LithoViewRule in MountStateRemountTest<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook.litho;

import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.facebook.litho.LayoutOutput.getLayoutOutput;
import static com.facebook.litho.SizeSpec.makeSizeSpec;
import static com.facebook.litho.testing.TestDrawableComponent.create;
import static com.facebook.litho.testing.helper.ComponentTestHelper.mountComponent;
import static org.assertj.core.api.Java6Assertions.assertThat;

import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.litho.config.TempComponentsConfigurations;
import com.facebook.litho.drawable.ComparableDrawable;
import com.facebook.litho.testing.LithoViewRule;
import com.facebook.litho.testing.TestComponent;
import com.facebook.litho.testing.TestDrawableComponent;
import com.facebook.litho.testing.TestViewComponent;
import com.facebook.litho.testing.Whitebox;
import com.facebook.litho.testing.helper.ComponentTestHelper;
import com.facebook.litho.testing.testrunner.LithoTestRunner;
import com.facebook.litho.widget.EditText;
import com.facebook.litho.widget.Text;
import com.facebook.rendercore.MountDelegateTarget;
import com.facebook.rendercore.MountItem;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(LithoTestRunner.class)
public class MountStateRemountTest {
  private ComponentContext mContext;
  public final @Rule LithoViewRule mLithoViewRule = new LithoViewRule();

  @Before
  public void setup() {
    TempComponentsConfigurations.setShouldDisableDrawableOutputs(true);
    mContext = new ComponentContext(getApplicationContext());
  }

  @Test
  public void testMountItemsHaveMountData() {
    final TestComponent component1 = create(mContext).build();
    final TestComponent component2 = create(mContext).build();

    final LithoView lithoView =
        mountComponent(
            mContext, Column.create(mContext).child(component1).child(component2).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();

    final MountDelegateTarget mountDelegateTarget = lithoView.getMountDelegateTarget();

    for (int i = 0; i < mountDelegateTarget.getMountItemCount(); i++) {
      MountItem item = mountDelegateTarget.getMountItemAt(i);
      assertThat(item.getMountData()).isOfAnyClassIn(LithoMountData.class);
    }
  }

  @Test
  public void testRemountSameLayoutState() {
    final TestComponent component1 = create(mContext).build();
    final TestComponent component2 = create(mContext).build();
    final TestComponent component3 = create(mContext).build();
    final TestComponent component4 = create(mContext).build();

    final LithoView lithoView =
        mountComponent(
            mContext, Column.create(mContext).child(component1).child(component2).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();

    mountComponent(
        mContext, lithoView, Column.create(mContext).child(component3).child(component4).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();
    assertThat(component3.isMounted()).isFalse();
    assertThat(component4.isMounted()).isFalse();

    final MountDelegateTarget mountDelegateTarget = lithoView.getMountDelegateTarget();

    final List<Component> components = new ArrayList<>();
    for (int i = 0; i < mountDelegateTarget.getMountItemCount(); i++) {
      components.add(getLayoutOutput(mountDelegateTarget.getMountItemAt(i)).getComponent());
    }

    assertThat(containsRef(components, component1)).isFalse();
    assertThat(containsRef(components, component2)).isFalse();
    assertThat(containsRef(components, component3)).isTrue();
    assertThat(containsRef(components, component4)).isTrue();
  }

  /**
   * There was a crash when mounting a drawing in place of a view. This test is here to make sure
   * this does not regress. To reproduce this crash the pools needed to be in a specific state as
   * view layout outputs and mount items were being re-used for drawables.
   */
  @Test
  public void testRemountDifferentMountType() throws IllegalAccessException, NoSuchFieldException {

    mLithoViewRule
        .setRoot(TestViewComponent.create(mContext).build())
        .setSizeSpecs(makeSizeSpec(10, SizeSpec.EXACTLY), makeSizeSpec(5, SizeSpec.EXACTLY));

    mLithoViewRule.attachToWindow().measure().layout().setSizeSpecs(10, 10);

    assertThat(mLithoViewRule.getLithoView().getChildCount()).isEqualTo(1);

    mLithoViewRule
        .setRoot(TestDrawableComponent.create(mContext).build())
        .setSizeSpecs(makeSizeSpec(10, SizeSpec.EXACTLY), makeSizeSpec(5, SizeSpec.EXACTLY));

    assertThat(mLithoViewRule.getLithoView().getDrawables().get(0)).isNotNull();
  }

  @Test
  public void testRemountNewLayoutState() {
    final TestComponent component1 = create(mContext).color(Color.RED).build();
    final TestComponent component2 = create(mContext).color(Color.BLUE).build();
    final TestComponent component3 = create(mContext).color(Color.GREEN).build();
    final TestComponent component4 = create(mContext).color(Color.YELLOW).build();

    final LithoView lithoView =
        mountComponent(
            mContext, Column.create(mContext).child(component1).child(component2).build());

    assertThat(component1.isMounted()).isTrue();
    assertThat(component2.isMounted()).isTrue();

    mountComponent(
{'fraction_non_alphanumeric': 0.1066350710900474, 'fraction_numerical': 0.007354142833796372, 'mean_word_length': 5.058910891089109, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2405148', 'n_tokens_mistral': 3433, 'n_tokens_neox': 3379, 'n_words': 743}