提交 14f2a42d 编写于 作者: G Gaëtan Muller 提交者: Takeshi Hagikura

#327: Kotlinize the test code (#346)

* Convert tests in `demo-playground`

* Convert tests in `flexbox`
上级 c462f8f4
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.apps.flexbox.test;
import com.google.android.flexbox.MainActivity;
import com.google.android.apps.flexbox.R;
import com.google.android.flexbox.AlignContent;
import com.google.android.flexbox.AlignItems;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexWrap;
import com.google.android.flexbox.FlexboxLayout;
import com.google.android.flexbox.JustifyContent;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import android.content.pm.ActivityInfo;
import android.support.design.widget.NavigationView;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.FlakyTest;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.view.MenuItemCompat;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.action.ViewActions.replaceText;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
/**
* Integration tests for {@link MainActivity}.
*/
@RunWith(AndroidJUnit4.class)
@MediumTest
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule<>(MainActivity.class);
@Test
@FlakyTest
public void testAddFlexItem() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
int beforeCount = flexboxLayout.getChildCount();
onView(withId(R.id.add_fab)).perform(click());
assertThat(flexboxLayout.getChildCount(), is(beforeCount + 1));
}
@Test
@FlakyTest
public void testRemoveFlexItem() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
int beforeCount = flexboxLayout.getChildCount();
onView(withId(R.id.remove_fab)).perform(click());
assertThat(flexboxLayout.getChildCount(), is(beforeCount - 1));
}
@Test
@FlakyTest
public void testConfigurationChange() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
onView(withId(R.id.add_fab)).perform(click());
onView(withId(R.id.add_fab)).perform(click());
onView(withId(R.id.add_fab)).perform(click());
int beforeCount = flexboxLayout.getChildCount();
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
// Verify the flex items are restored across the configuration change.
assertThat(flexboxLayout.getChildCount(), is(beforeCount));
}
@Test
@SuppressWarnings("unchecked")
@FlakyTest
public void testFlexDirectionSpinner() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.nav_view);
assertNotNull(navigationView);
Menu menu = navigationView.getMenu();
final Spinner spinner = (Spinner) MenuItemCompat
.getActionView(menu.findItem(R.id.menu_item_flex_direction));
ArrayAdapter<CharSequence> spinnerAdapter = (ArrayAdapter<CharSequence>)
spinner.getAdapter();
final int columnPosition = spinnerAdapter.getPosition(activity.getString(R.string.column));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(columnPosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getFlexDirection(), is(FlexDirection.COLUMN));
final int rowReversePosition = spinnerAdapter
.getPosition(activity.getString(R.string.row_reverse));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(rowReversePosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getFlexDirection(), is(FlexDirection.ROW_REVERSE));
}
@Test
@SuppressWarnings("unchecked")
@FlakyTest
public void testFlexWrapSpinner() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.nav_view);
assertNotNull(navigationView);
Menu menu = navigationView.getMenu();
final Spinner spinner = (Spinner) MenuItemCompat
.getActionView(menu.findItem(R.id.menu_item_flex_wrap));
ArrayAdapter<CharSequence> spinnerAdapter = (ArrayAdapter<CharSequence>)
spinner.getAdapter();
final int wrapReversePosition = spinnerAdapter
.getPosition(activity.getString(R.string.wrap_reverse));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(wrapReversePosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getFlexWrap(), is(FlexWrap.WRAP_REVERSE));
final int noWrapPosition = spinnerAdapter
.getPosition(activity.getString(R.string.nowrap));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(noWrapPosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getFlexWrap(), is(FlexWrap.NOWRAP));
}
@Test
@SuppressWarnings("unchecked")
@FlakyTest
public void testJustifyContentSpinner() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.nav_view);
assertNotNull(navigationView);
Menu menu = navigationView.getMenu();
final Spinner spinner = (Spinner) MenuItemCompat
.getActionView(menu.findItem(R.id.menu_item_justify_content));
ArrayAdapter<CharSequence> spinnerAdapter = (ArrayAdapter<CharSequence>)
spinner.getAdapter();
final int spaceBetweenPosition = spinnerAdapter
.getPosition(activity.getString(R.string.space_between));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(spaceBetweenPosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getJustifyContent(),
is(JustifyContent.SPACE_BETWEEN));
final int centerPosition = spinnerAdapter
.getPosition(activity.getString(R.string.center));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(centerPosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getJustifyContent(), is(JustifyContent.CENTER));
}
@Test
@SuppressWarnings("unchecked")
@FlakyTest
public void testAlignItemsSpinner() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.nav_view);
assertNotNull(navigationView);
Menu menu = navigationView.getMenu();
final Spinner spinner = (Spinner) MenuItemCompat
.getActionView(menu.findItem(R.id.menu_item_align_items));
ArrayAdapter<CharSequence> spinnerAdapter = (ArrayAdapter<CharSequence>)
spinner.getAdapter();
final int baselinePosition = spinnerAdapter
.getPosition(activity.getString(R.string.baseline));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(baselinePosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getAlignItems(),
is(AlignItems.BASELINE));
final int flexEndPosition = spinnerAdapter
.getPosition(activity.getString(R.string.flex_end));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(flexEndPosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getAlignItems(), is(AlignItems.FLEX_END));
}
@Test
@SuppressWarnings("unchecked")
@FlakyTest
public void testAlignContentSpinner() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.nav_view);
assertNotNull(navigationView);
Menu menu = navigationView.getMenu();
final Spinner spinner = (Spinner) MenuItemCompat
.getActionView(menu.findItem(R.id.menu_item_align_content));
ArrayAdapter<CharSequence> spinnerAdapter = (ArrayAdapter<CharSequence>)
spinner.getAdapter();
final int spaceAroundPosition = spinnerAdapter
.getPosition(activity.getString(R.string.space_around));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(spaceAroundPosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getAlignContent(),
is(AlignContent.SPACE_AROUND));
final int stretchPosition = spinnerAdapter
.getPosition(activity.getString(R.string.stretch));
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
spinner.setSelection(stretchPosition);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertThat(flexboxLayout.getAlignContent(), is(AlignContent.STRETCH));
}
@Test
@FlakyTest
public void testEditFragment_changeOrder() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
onView(withId(R.id.textview1)).perform(click());
onView(withId(R.id.edit_text_order)).perform(replaceText("3"), closeSoftKeyboard());
onView(withId(R.id.button_ok)).perform(click());
TextView first = (TextView) flexboxLayout.getReorderedChildAt(0);
TextView second = (TextView) flexboxLayout.getReorderedChildAt(1);
TextView third = (TextView) flexboxLayout.getReorderedChildAt(2);
assertThat(first.getText().toString(), is("2"));
assertThat(second.getText().toString(), is("3"));
assertThat(third.getText().toString(), is("1"));
}
@Test
@FlakyTest
public void testEditFragment_changeFlexGrow() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
onView(withId(R.id.textview1)).perform(click());
onView(withId(R.id.edit_text_flex_grow)).perform(replaceText("1"), closeSoftKeyboard());
onView(withId(R.id.button_ok)).perform(click());
TextView first = (TextView) activity.findViewById(R.id.textview1);
TextView second = (TextView) activity.findViewById(R.id.textview2);
TextView third = (TextView) activity.findViewById(R.id.textview3);
assertNotNull(first);
assertNotNull(second);
assertNotNull(third);
assertThat(first.getWidth(),
is(flexboxLayout.getWidth() - second.getWidth() - third.getWidth()));
}
@Test
@FlakyTest
public void testEditFragment_changeFlexGrowFloat() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
onView(withId(R.id.textview1)).perform(click());
onView(withId(R.id.edit_text_flex_grow)).perform(replaceText("1.0"), closeSoftKeyboard());
onView(withId(R.id.button_ok)).perform(click());
TextView first = (TextView) activity.findViewById(R.id.textview1);
TextView second = (TextView) activity.findViewById(R.id.textview2);
TextView third = (TextView) activity.findViewById(R.id.textview3);
assertNotNull(first);
assertNotNull(second);
assertNotNull(third);
assertThat(first.getWidth(),
is(flexboxLayout.getWidth() - second.getWidth() - third.getWidth()));
}
@Test
@FlakyTest
public void testEditFragment_changeFlexBasisPercent() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
onView(withId(R.id.textview1)).perform(click());
onView(withId(R.id.edit_text_flex_basis_percent))
.perform(replaceText("50"), closeSoftKeyboard());
onView(withId(R.id.button_ok)).perform(click());
TextView first = (TextView) activity.findViewById(R.id.textview1);
TextView second = (TextView) activity.findViewById(R.id.textview2);
TextView third = (TextView) activity.findViewById(R.id.textview3);
assertNotNull(first);
assertNotNull(second);
assertNotNull(third);
assertTrue(first.getWidth() - 1 <= flexboxLayout.getWidth() / 2
|| flexboxLayout.getWidth() / 2 <= first.getWidth() + 1);
}
@Test
@FlakyTest
public void testSwitchRecyclerViewFragment() {
MainActivity activity = mActivityRule.getActivity();
FlexboxLayout flexboxLayout = (FlexboxLayout) activity.findViewById(R.id.flexbox_layout);
assertNotNull(flexboxLayout);
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.nav_view);
assertNotNull(navigationView);
assertNull(activity.findViewById(R.id.recyclerview));
assertNotNull(activity.findViewById(R.id.flexbox_layout));
final RadioGroup radioGroup = (RadioGroup) navigationView.getHeaderView(0)
.findViewById(R.id.radiogroup_container_implementation);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
radioGroup.check(R.id.radiobutton_recyclerview);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
assertNotNull(activity.findViewById(R.id.recyclerview));
assertNull(activity.findViewById(R.id.flexbox_layout));
}
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.apps.flexbox.test
import android.content.pm.ActivityInfo
import android.support.design.widget.NavigationView
import android.support.test.InstrumentationRegistry
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.*
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.filters.FlakyTest
import android.support.test.filters.MediumTest
import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
import android.view.View
import android.widget.ArrayAdapter
import android.widget.RadioGroup
import android.widget.Spinner
import android.widget.TextView
import com.google.android.apps.flexbox.R
import com.google.android.flexbox.*
import junit.framework.Assert.*
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.Is.`is`
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
/**
* Integration tests for [MainActivity].
*/
@RunWith(AndroidJUnit4::class)
@MediumTest
class MainActivityTest {
@JvmField
@Rule
var activityRule = ActivityTestRule(MainActivity::class.java)
@Test
@FlakyTest
fun testAddFlexItem() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
val beforeCount = flexboxLayout.childCount
onView(withId(R.id.add_fab)).perform(click())
assertThat(flexboxLayout.childCount, `is`(beforeCount + 1))
}
@Test
@FlakyTest
fun testRemoveFlexItem() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
val beforeCount = flexboxLayout.childCount
onView(withId(R.id.remove_fab)).perform(click())
assertThat(flexboxLayout.childCount, `is`(beforeCount - 1))
}
@Test
@FlakyTest
fun testConfigurationChange() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
onView(withId(R.id.add_fab)).perform(click())
onView(withId(R.id.add_fab)).perform(click())
onView(withId(R.id.add_fab)).perform(click())
val beforeCount = flexboxLayout.childCount
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
// Verify the flex items are restored across the configuration change.
assertThat(flexboxLayout.childCount, `is`(beforeCount))
}
@Test
@FlakyTest
fun testFlexDirectionSpinner() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
assertNotNull(navigationView)
val menu = navigationView.menu
val spinner = menu.findItem(R.id.menu_item_flex_direction).actionView as Spinner
val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>
val columnPosition = spinnerAdapter.getPosition(activity.getString(R.string.column))
activity.runOnUiThread { spinner.setSelection(columnPosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.flexDirection, `is`(FlexDirection.COLUMN))
val rowReversePosition = spinnerAdapter.getPosition(activity.getString(R.string.row_reverse))
activity.runOnUiThread { spinner.setSelection(rowReversePosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.flexDirection, `is`(FlexDirection.ROW_REVERSE))
}
@Test
@FlakyTest
fun testFlexWrapSpinner() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
assertNotNull(navigationView)
val menu = navigationView.menu
val spinner = menu.findItem(R.id.menu_item_flex_wrap).actionView as Spinner
val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>
val wrapReversePosition = spinnerAdapter.getPosition(activity.getString(R.string.wrap_reverse))
activity.runOnUiThread { spinner.setSelection(wrapReversePosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.flexWrap, `is`(FlexWrap.WRAP_REVERSE))
val noWrapPosition = spinnerAdapter.getPosition(activity.getString(R.string.nowrap))
activity.runOnUiThread { spinner.setSelection(noWrapPosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.flexWrap, `is`(FlexWrap.NOWRAP))
}
@Test
@FlakyTest
fun testJustifyContentSpinner() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
assertNotNull(flexboxLayout)
val navigationView = activity.findViewById<View>(R.id.nav_view) as NavigationView
assertNotNull(navigationView)
val menu = navigationView.menu
val spinner = menu.findItem(R.id.menu_item_justify_content).actionView as Spinner
val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>
val spaceBetweenPosition = spinnerAdapter.getPosition(activity.getString(R.string.space_between))
activity.runOnUiThread { spinner.setSelection(spaceBetweenPosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.justifyContent, `is`(JustifyContent.SPACE_BETWEEN))
val centerPosition = spinnerAdapter.getPosition(activity.getString(R.string.center))
activity.runOnUiThread { spinner.setSelection(centerPosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.justifyContent, `is`(JustifyContent.CENTER))
}
@Test
@FlakyTest
fun testAlignItemsSpinner() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
assertNotNull(navigationView)
val menu = navigationView.menu
val spinner = menu.findItem(R.id.menu_item_align_items).actionView as Spinner
val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>
val baselinePosition = spinnerAdapter.getPosition(activity.getString(R.string.baseline))
activity.runOnUiThread { spinner.setSelection(baselinePosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.alignItems, `is`(AlignItems.BASELINE))
val flexEndPosition = spinnerAdapter.getPosition(activity.getString(R.string.flex_end))
activity.runOnUiThread { spinner.setSelection(flexEndPosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.alignItems, `is`(AlignItems.FLEX_END))
}
@Test
@FlakyTest
fun testAlignContentSpinner() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
assertNotNull(navigationView)
val menu = navigationView.menu
val spinner = menu.findItem(R.id.menu_item_align_content).actionView as Spinner
val spinnerAdapter = spinner.adapter as ArrayAdapter<CharSequence>
val spaceAroundPosition = spinnerAdapter.getPosition(activity.getString(R.string.space_around))
activity.runOnUiThread { spinner.setSelection(spaceAroundPosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.alignContent, `is`(AlignContent.SPACE_AROUND))
val stretchPosition = spinnerAdapter.getPosition(activity.getString(R.string.stretch))
activity.runOnUiThread { spinner.setSelection(stretchPosition) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertThat(flexboxLayout.alignContent, `is`(AlignContent.STRETCH))
}
@Test
@FlakyTest
fun testEditFragment_changeOrder() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
assertNotNull(flexboxLayout)
onView(withId(R.id.textview1)).perform(click())
onView(withId(R.id.edit_text_order)).perform(replaceText("3"), closeSoftKeyboard())
onView(withId(R.id.button_ok)).perform(click())
val first = flexboxLayout.getReorderedChildAt(0) as TextView
val second = flexboxLayout.getReorderedChildAt(1) as TextView
val third = flexboxLayout.getReorderedChildAt(2) as TextView
assertThat(first.text.toString(), `is`("2"))
assertThat(second.text.toString(), `is`("3"))
assertThat(third.text.toString(), `is`("1"))
}
@Test
@FlakyTest
fun testEditFragment_changeFlexGrow() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
assertNotNull(flexboxLayout)
onView(withId(R.id.textview1)).perform(click())
onView(withId(R.id.edit_text_flex_grow)).perform(replaceText("1"), closeSoftKeyboard())
onView(withId(R.id.button_ok)).perform(click())
val first = activity.findViewById<View>(R.id.textview1) as TextView
val second = activity.findViewById<View>(R.id.textview2) as TextView
val third = activity.findViewById<View>(R.id.textview3) as TextView
assertNotNull(first)
assertNotNull(second)
assertNotNull(third)
assertThat(first.width, `is`(flexboxLayout.width - second.width - third.width))
}
@Test
@FlakyTest
fun testEditFragment_changeFlexGrowFloat() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
assertNotNull(flexboxLayout)
onView(withId(R.id.textview1)).perform(click())
onView(withId(R.id.edit_text_flex_grow)).perform(replaceText("1.0"), closeSoftKeyboard())
onView(withId(R.id.button_ok)).perform(click())
val first = activity.findViewById<View>(R.id.textview1) as TextView
val second = activity.findViewById<View>(R.id.textview2) as TextView
val third = activity.findViewById<View>(R.id.textview3) as TextView
assertNotNull(first)
assertNotNull(second)
assertNotNull(third)
assertThat(first.width, `is`(flexboxLayout.width - second.width - third.width))
}
@Test
@FlakyTest
fun testEditFragment_changeFlexBasisPercent() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<View>(R.id.flexbox_layout) as FlexboxLayout
assertNotNull(flexboxLayout)
onView(withId(R.id.textview1)).perform(click())
onView(withId(R.id.edit_text_flex_basis_percent))
.perform(replaceText("50"), closeSoftKeyboard())
onView(withId(R.id.button_ok)).perform(click())
val first = activity.findViewById<TextView>(R.id.textview1)
val second = activity.findViewById<TextView>(R.id.textview2)
val third = activity.findViewById<TextView>(R.id.textview3)
assertNotNull(first)
assertNotNull(second)
assertNotNull(third)
assertTrue(first.width - 1 <= flexboxLayout.width / 2 || flexboxLayout.width / 2 <= first.width + 1)
}
@Test
@FlakyTest
fun testSwitchRecyclerViewFragment() {
val activity = activityRule.activity
val flexboxLayout = activity.findViewById<FlexboxLayout>(R.id.flexbox_layout)
assertNotNull(flexboxLayout)
val navigationView = activity.findViewById<NavigationView>(R.id.nav_view)
assertNotNull(navigationView)
assertNull(activity.findViewById(R.id.recyclerview))
assertNotNull(activity.findViewById(R.id.flexbox_layout))
val radioGroup = navigationView.getHeaderView(0)
.findViewById<RadioGroup>(R.id.radiogroup_container_implementation)
activity.runOnUiThread { radioGroup.check(R.id.radiobutton_recyclerview) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
assertNotNull(activity.findViewById(R.id.recyclerview))
assertNull(activity.findViewById(R.id.flexbox_layout))
}
}
......@@ -15,6 +15,7 @@
*/
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply from: 'maven.gradle'
apply from: 'bintray.gradle'
......@@ -48,4 +49,5 @@ dependencies {
androidTestCompile "com.android.support:support-annotations:${rootProject.ext.supportLibVersion}"
androidTestCompile "com.android.support.test:runner:${rootProject.ext.testRunnerVersion}"
androidTestCompile "com.android.support.test.espresso:espresso-core:${rootProject.ext.espressoVersion}"
androidTestCompile "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.kotlinVersion}"
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.flexbox;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Fake implementation of {@link FlexContainer}.
*/
class FakeFlexContainer implements FlexContainer {
private List<View> mViews = new ArrayList<>();
private List<FlexLine> mFlexLines = new ArrayList<>();
@FlexDirection
private int mFlexDirection = FlexDirection.ROW;
@FlexWrap
private int mFlexWrap = FlexWrap.WRAP;
@JustifyContent
private int mJustifyContent = JustifyContent.FLEX_START;
@AlignItems
private int mAlignItems = AlignItems.STRETCH;
@AlignContent
private int mAlignContent = AlignContent.STRETCH;
@Override
public int getFlexItemCount() {
return mViews.size();
}
@Override
public View getFlexItemAt(int index) {
return mViews.get(index);
}
@Override
public View getReorderedFlexItemAt(int index) {
return mViews.get(index);
}
@Override
public void addView(View view) {
mViews.add(view);
}
@Override
public void addView(View view, int index) {
mViews.add(index, view);
}
@Override
public void removeAllViews() {
mViews.clear();
}
@Override
public void removeViewAt(int index) {
mViews.remove(index);
}
@Override
public int getFlexDirection() {
return mFlexDirection;
}
@Override
public void setFlexDirection(@FlexDirection int flexDirection) {
mFlexDirection = flexDirection;
}
@Override
public int getFlexWrap() {
return mFlexWrap;
}
@Override
public void setFlexWrap(@FlexWrap int flexWrap) {
mFlexWrap = flexWrap;
}
@Override
public int getJustifyContent() {
return mJustifyContent;
}
@Override
public void setJustifyContent(@JustifyContent int justifyContent) {
mJustifyContent = justifyContent;
}
@Override
public int getAlignContent() {
return mAlignContent;
}
@Override
public void setAlignContent(@AlignContent int alignContent) {
mAlignContent = alignContent;
}
@Override
public int getAlignItems() {
return mAlignItems;
}
@Override
public void setAlignItems(@AlignItems int alignItems) {
mAlignItems = alignItems;
}
@Override
public List<FlexLine> getFlexLines() {
return mFlexLines;
}
@Override
public boolean isMainAxisDirectionHorizontal() {
return mFlexDirection == FlexDirection.ROW || mFlexDirection == FlexDirection.ROW_REVERSE;
}
@Override
public int getDecorationLengthMainAxis(View view, int index, int indexInFlexLine) {
return 0;
}
@Override
public int getDecorationLengthCrossAxis(View view) {
return 0;
}
@Override
public int getPaddingTop() {
return 0;
}
@Override
public int getPaddingLeft() {
return 0;
}
@Override
public int getPaddingRight() {
return 0;
}
@Override
public int getPaddingBottom() {
return 0;
}
@Override
public int getPaddingStart() {
return 0;
}
@Override
public int getPaddingEnd() {
return 0;
}
@Override
public int getChildWidthMeasureSpec(int widthSpec, int padding, int childDimension) {
return ViewGroup.getChildMeasureSpec(widthSpec, padding, childDimension);
}
@Override
public int getChildHeightMeasureSpec(int heightSpec, int padding, int childDimension) {
return ViewGroup.getChildMeasureSpec(heightSpec, padding, childDimension);
}
@Override
public int getLargestMainSize() {
int largestSize = Integer.MIN_VALUE;
for (FlexLine flexLine : mFlexLines) {
largestSize = Math.max(largestSize, flexLine.mMainSize);
}
return largestSize;
}
@Override
public int getSumOfCrossSize() {
int sum = 0;
for (int i = 0, size = mFlexLines.size(); i < size; i++) {
FlexLine flexLine = mFlexLines.get(i);
sum += flexLine.mCrossSize;
}
return sum;
}
@Override
public void onNewFlexItemAdded(View view, int index, int indexInFlexLine, FlexLine flexLine) {
// No op
}
@Override
public void onNewFlexLineAdded(FlexLine flexLine) {
// No op
}
@Override
public void setFlexLines(List<FlexLine> flexLines) {
mFlexLines = flexLines;
}
@Override
public List<FlexLine> getFlexLinesInternal() {
return mFlexLines;
}
@Override
public void updateViewCache(int position, View view) {
// No op
}
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.flexbox
import android.view.View
import android.view.ViewGroup
/**
* Fake implementation of [FlexContainer].
*/
internal class FakeFlexContainer : FlexContainer {
private val views = mutableListOf<View>()
private var flexLines = mutableListOf<FlexLine>()
@FlexDirection
private var flexDirection = FlexDirection.ROW
@FlexWrap
private var flexWrap = FlexWrap.WRAP
@JustifyContent
private var justifyContent = JustifyContent.FLEX_START
@AlignItems
private var alignItems = AlignItems.STRETCH
@AlignContent
private var alignContent = AlignContent.STRETCH
override fun getFlexItemCount() = views.size
override fun getFlexItemAt(index: Int) = views[index]
override fun getReorderedFlexItemAt(index: Int) = views[index]
override fun addView(view: View) {
views.add(view)
}
override fun addView(view: View, index: Int) {
views.add(index, view)
}
override fun removeAllViews() {
views.clear()
}
override fun removeViewAt(index: Int) {
views.removeAt(index)
}
override fun getFlexDirection() = flexDirection
override fun setFlexDirection(@FlexDirection flexDirection: Int) {
this.flexDirection = flexDirection
}
override fun getFlexWrap() = flexWrap
override fun setFlexWrap(@FlexWrap flexWrap: Int) {
this.flexWrap = flexWrap
}
override fun getJustifyContent() = justifyContent
override fun setJustifyContent(@JustifyContent justifyContent: Int) {
this.justifyContent = justifyContent
}
override fun getAlignContent() = alignContent
override fun setAlignContent(@AlignContent alignContent: Int) {
this.alignContent = alignContent
}
override fun getAlignItems() = alignItems
override fun setAlignItems(@AlignItems alignItems: Int) {
this.alignItems = alignItems
}
override fun getFlexLines() = flexLines
override fun isMainAxisDirectionHorizontal(): Boolean {
return flexDirection == FlexDirection.ROW || flexDirection == FlexDirection.ROW_REVERSE
}
override fun getDecorationLengthMainAxis(view: View, index: Int, indexInFlexLine: Int) = 0
override fun getDecorationLengthCrossAxis(view: View) = 0
override fun getPaddingTop() = 0
override fun getPaddingLeft() = 0
override fun getPaddingRight() = 0
override fun getPaddingBottom() = 0
override fun getPaddingStart() = 0
override fun getPaddingEnd() = 0
override fun getChildWidthMeasureSpec(widthSpec: Int, padding: Int, childDimension: Int): Int {
return ViewGroup.getChildMeasureSpec(widthSpec, padding, childDimension)
}
override fun getChildHeightMeasureSpec(heightSpec: Int, padding: Int, childDimension: Int): Int {
return ViewGroup.getChildMeasureSpec(heightSpec, padding, childDimension)
}
override fun getLargestMainSize() = flexLines.maxBy { it.mMainSize }?.mMainSize ?: Integer.MIN_VALUE
override fun getSumOfCrossSize() = flexLines.sumBy { it.mCrossSize }
override fun onNewFlexItemAdded(view: View, index: Int, indexInFlexLine: Int, flexLine: FlexLine) = Unit
override fun onNewFlexLineAdded(flexLine: FlexLine) = Unit
override fun setFlexLines(flexLines: List<FlexLine>) {
this.flexLines = flexLines.toMutableList()
}
override fun getFlexLinesInternal() = flexLines
override fun updateViewCache(position: Int, view: View) = Unit
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.flexbox
import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
import android.view.View
import com.google.android.flexbox.test.FlexboxTestActivity
import com.google.android.flexbox.test.IsEqualAllowingError.Companion.isEqualAllowingError
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertNotNull
import org.hamcrest.Matchers.`is`
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
/**
* Unit tests for [FlexboxHelper].
*/
@RunWith(AndroidJUnit4::class)
class FlexboxHelperTest {
@JvmField
@Rule
var activityRule = ActivityTestRule(FlexboxTestActivity::class.java)
private lateinit var flexboxHelper: FlexboxHelper
private lateinit var flexContainer: FlexContainer
@Before
fun setUp() {
flexContainer = FakeFlexContainer()
flexboxHelper = FlexboxHelper(flexContainer)
}
@Test
@Throws(Throwable::class)
fun testCalculateHorizontalFlexLines() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 100)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(200, 100)
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(300, 100)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(400, 100)
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexWrap = FlexWrap.WRAP
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
flexboxHelper.ensureIndexToFlexLine(flexContainer.flexItemCount)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateHorizontalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
assertEquals(3, result.mFlexLines.size)
assertEquals(300, result.mFlexLines[0].mainSize)
assertEquals(300, result.mFlexLines[1].mainSize)
assertEquals(400, result.mFlexLines[2].mainSize)
assertEquals(100, result.mFlexLines[0].crossSize)
assertEquals(100, result.mFlexLines[1].crossSize)
assertEquals(100, result.mFlexLines[2].crossSize)
assertNotNull(flexboxHelper.mIndexToFlexLine)
assertEquals(0, flexboxHelper.mIndexToFlexLine!![0])
assertEquals(0, flexboxHelper.mIndexToFlexLine!![1])
assertEquals(1, flexboxHelper.mIndexToFlexLine!![2])
assertEquals(2, flexboxHelper.mIndexToFlexLine!![3])
val firstLine = result.mFlexLines[0]
assertEquals(0, firstLine.mFirstIndex)
assertEquals(1, firstLine.mLastIndex)
val secondLine = result.mFlexLines[1]
assertEquals(2, secondLine.mFirstIndex)
assertEquals(2, secondLine.mLastIndex)
val thirdLine = result.mFlexLines[2]
assertEquals(3, thirdLine.mFirstIndex)
assertEquals(3, thirdLine.mLastIndex)
}
@Test
@Throws(Throwable::class)
fun testCalculateVerticalFlexLines() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 100)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(100, 200)
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(100, 300)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(100, 400)
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexWrap = FlexWrap.WRAP
flexContainer.flexDirection = FlexDirection.COLUMN
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
flexboxHelper.ensureIndexToFlexLine(flexContainer.flexItemCount)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateVerticalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
assertEquals(3, result.mFlexLines.size)
assertEquals(300, result.mFlexLines[0].mainSize)
assertEquals(300, result.mFlexLines[1].mainSize)
assertEquals(400, result.mFlexLines[2].mainSize)
assertEquals(100, result.mFlexLines[0].crossSize)
assertEquals(100, result.mFlexLines[1].crossSize)
assertEquals(100, result.mFlexLines[2].crossSize)
assertNotNull(flexboxHelper.mIndexToFlexLine)
assertEquals(0, flexboxHelper.mIndexToFlexLine!![0])
assertEquals(0, flexboxHelper.mIndexToFlexLine!![1])
assertEquals(1, flexboxHelper.mIndexToFlexLine!![2])
assertEquals(2, flexboxHelper.mIndexToFlexLine!![3])
val firstLine = result.mFlexLines[0]
assertEquals(0, firstLine.mFirstIndex)
assertEquals(1, firstLine.mLastIndex)
val secondLine = result.mFlexLines[1]
assertEquals(2, secondLine.mFirstIndex)
assertEquals(2, secondLine.mLastIndex)
val thirdLine = result.mFlexLines[2]
assertEquals(3, thirdLine.mFirstIndex)
assertEquals(3, thirdLine.mLastIndex)
}
@Test
@Throws(Throwable::class)
fun testDetermineMainSize_direction_row_flexGrowSet() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 100)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(200, 100)
lp2.flexGrow = 1.0f
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(300, 100)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(400, 100)
lp4.flexGrow = 2.0f
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexDirection = FlexDirection.ROW
flexContainer.flexWrap = FlexWrap.WRAP
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateHorizontalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
flexContainer.flexLines = result.mFlexLines
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
assertThat(view1.measuredWidth, `is`(100))
assertThat(view1.measuredHeight, `is`(100))
// view2 will expand to fill the left space in the first flex line since flex grow is set
assertThat(view2.measuredWidth, `is`(400))
assertThat(view2.measuredHeight, `is`(100))
assertThat(view3.measuredWidth, `is`(300))
assertThat(view3.measuredHeight, `is`(100))
// view4 will expand to fill the left space in the first flex line since flex grow is set
assertThat(view4.measuredWidth, `is`(500))
assertThat(view4.measuredHeight, `is`(100))
}
@Test
@Throws(Throwable::class)
fun testDetermineMainSize_direction_column_flexGrowSet() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 100)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(100, 200)
lp2.flexGrow = 1.0f
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(100, 300)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(100, 400)
lp4.flexGrow = 2.0f
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexDirection = FlexDirection.COLUMN
flexContainer.flexWrap = FlexWrap.WRAP
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateVerticalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
flexContainer.flexLines = result.mFlexLines
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
assertThat(view1.measuredWidth, `is`(100))
assertThat(view1.measuredHeight, `is`(100))
assertThat(view2.measuredWidth, `is`(100))
// view2 will expand to fill the left space in the first flex line since flex grow is set
assertThat(view2.measuredHeight, `is`(400))
assertThat(view3.measuredWidth, `is`(100))
assertThat(view3.measuredHeight, `is`(300))
assertThat(view4.measuredWidth, `is`(100))
// view4 will expand to fill the left space in the first flex line since flex grow is set
assertThat(view4.measuredHeight, `is`(500))
}
@Test
@Throws(Throwable::class)
fun testDetermineMainSize_direction_row_flexShrinkSet() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(200, 100)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(200, 100)
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(200, 100)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(200, 100)
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexDirection = FlexDirection.ROW
flexContainer.flexWrap = FlexWrap.NOWRAP
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateVerticalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
flexContainer.flexLines = result.mFlexLines
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
// Flex shrink is set to 1.0 (default value) for all views.
// They should be shrank equally for the amount overflown the width
assertThat(view1.measuredWidth, `is`(125))
assertThat(view1.measuredHeight, `is`(100))
assertThat(view2.measuredWidth, `is`(125))
assertThat(view2.measuredHeight, `is`(100))
assertThat(view3.measuredWidth, `is`(125))
assertThat(view3.measuredHeight, `is`(100))
assertThat(view4.measuredWidth, `is`(125))
assertThat(view4.measuredHeight, `is`(100))
}
@Test
@Throws(Throwable::class)
fun testDetermineMainSize_direction_column_flexShrinkSet() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 200)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(100, 200)
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(100, 200)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(100, 200)
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexDirection = FlexDirection.COLUMN
flexContainer.flexWrap = FlexWrap.NOWRAP
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.UNSPECIFIED)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateVerticalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
flexContainer.flexLines = result.mFlexLines
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
// Flex shrink is set to 1.0 (default value) for all views.
// They should be shrank equally for the amount overflown the height
assertThat(view1.measuredWidth, `is`(100))
assertThat(view1.measuredHeight, `is`(125))
assertThat(view2.measuredWidth, `is`(100))
assertThat(view2.measuredHeight, `is`(125))
assertThat(view3.measuredWidth, `is`(100))
assertThat(view3.measuredHeight, `is`(125))
assertThat(view4.measuredWidth, `is`(100))
assertThat(view4.measuredHeight, `is`(125))
}
@Test
@Throws(Throwable::class)
fun testDetermineCrossSize_direction_row_alignContent_stretch() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 100)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(200, 100)
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(300, 100)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(400, 100)
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexDirection = FlexDirection.ROW
flexContainer.flexWrap = FlexWrap.WRAP
flexContainer.alignContent = AlignContent.STRETCH
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateHorizontalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
flexContainer.flexLines = result.mFlexLines
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
flexboxHelper.determineCrossSize(widthMeasureSpec, heightMeasureSpec, 0)
flexboxHelper.stretchViews()
// align content is set to Align.STRETCH, the cross size for each flex line is stretched
// to distribute the remaining free space along the cross axis
// (remaining height in this case)
assertThat(view1.measuredHeight, isEqualAllowingError(333))
assertThat(view2.measuredHeight, isEqualAllowingError(333))
assertThat(view3.measuredHeight, isEqualAllowingError(333))
assertThat(view4.measuredHeight, isEqualAllowingError(333))
}
@Test
@Throws(Throwable::class)
fun testDetermineCrossSize_direction_column_alignContent_stretch() {
val activity = activityRule.activity
val lp1 = FlexboxLayout.LayoutParams(100, 100)
val view1 = View(activity)
view1.layoutParams = lp1
val lp2 = FlexboxLayout.LayoutParams(100, 200)
val view2 = View(activity)
view2.layoutParams = lp2
val lp3 = FlexboxLayout.LayoutParams(100, 300)
val view3 = View(activity)
view3.layoutParams = lp3
val lp4 = FlexboxLayout.LayoutParams(100, 400)
val view4 = View(activity)
view4.layoutParams = lp4
flexContainer.addView(view1)
flexContainer.addView(view2)
flexContainer.addView(view3)
flexContainer.addView(view4)
flexContainer.flexDirection = FlexDirection.COLUMN
flexContainer.flexWrap = FlexWrap.WRAP
flexContainer.alignContent = AlignContent.STRETCH
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
val result = FlexboxHelper.FlexLinesResult()
flexboxHelper.calculateVerticalFlexLines(result, widthMeasureSpec, heightMeasureSpec)
flexContainer.flexLines = result.mFlexLines
flexboxHelper.determineMainSize(widthMeasureSpec, heightMeasureSpec)
flexboxHelper.determineCrossSize(widthMeasureSpec, heightMeasureSpec, 0)
flexboxHelper.stretchViews()
// align content is set to Align.STRETCH, the cross size for each flex line is stretched
// to distribute the remaining free space along the cross axis
// (remaining width in this case)
assertThat(view1.measuredWidth, isEqualAllowingError(333))
assertThat(view2.measuredWidth, isEqualAllowingError(333))
assertThat(view3.measuredWidth, isEqualAllowingError(333))
assertThat(view4.measuredWidth, isEqualAllowingError(333))
}
@Test
fun testMakeCombinedLong() {
var higher = -1
var lower = 10
var combined = flexboxHelper.makeCombinedLong(lower, higher)
assertThat(flexboxHelper.extractHigherInt(combined), `is`(higher))
assertThat(flexboxHelper.extractLowerInt(combined), `is`(lower))
higher = Integer.MAX_VALUE
lower = Integer.MIN_VALUE
combined = flexboxHelper.makeCombinedLong(lower, higher)
assertThat(flexboxHelper.extractHigherInt(combined), `is`(higher))
assertThat(flexboxHelper.extractLowerInt(combined), `is`(lower))
higher = View.MeasureSpec.makeMeasureSpec(500, View.MeasureSpec.EXACTLY)
lower = View.MeasureSpec.makeMeasureSpec(300, View.MeasureSpec.UNSPECIFIED)
combined = flexboxHelper.makeCombinedLong(lower, higher)
assertThat(flexboxHelper.extractHigherInt(combined), `is`(higher))
assertThat(flexboxHelper.extractLowerInt(combined), `is`(lower))
}
}
......@@ -14,26 +14,26 @@
* limitations under the License.
*/
package com.google.android.flexbox.test;
package com.google.android.flexbox.test
import android.app.Activity;
import android.content.res.Configuration;
import android.util.Log;
import android.app.Activity
import android.content.res.Configuration
import android.util.Log
import com.google.android.flexbox.FlexboxLayout;
import com.google.android.flexbox.FlexboxLayout
/**
* Activity for testing the {@link FlexboxLayout} that handles configuration changes by itself
* Activity for testing the [FlexboxLayout] that handles configuration changes by itself
* instead of letting the system take care of those.
*/
public class ConfigChangeActivity extends Activity {
class ConfigChangeActivity : Activity() {
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
private static final String TAG = "ConfigChangeActivity";
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged: " + newConfig)
}
Log.d(TAG, "onConfigurationChanged: " + newConfig);
companion object {
private const val TAG = "ConfigChangeActivity"
}
}
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertThat;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.CoordinatesProvider;
import android.support.test.espresso.action.GeneralLocation;
import android.support.test.espresso.action.GeneralSwipeAction;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Swipe;
import android.support.test.filters.FlakyTest;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexLine;
import com.google.android.flexbox.FlexboxLayoutManager;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Integration tests for {@link FlexboxLayoutManager} with the Activity that handles configration
* changes manually.
*/
@RunWith(AndroidJUnit4.class)
@MediumTest
public class FlexboxLayoutManagerConfigChangeTest {
@Rule
public ActivityTestRule<ConfigChangeActivity> mActivityRule =
new ActivityTestRule<>(ConfigChangeActivity.class);
@Test
@FlakyTest
public void testFlexLinesDiscardedOnOrientationChange_direction_row() throws Throwable {
// Verifies the case that the calculated Flex lines are correctly discarded when a
// orientation
// happens with an Activity that handles configuration changes manually
final ConfigChangeActivity activity = mActivityRule.getActivity();
final FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(activity);
final TestAdapter adapter = new TestAdapter();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.recyclerview);
RecyclerView recyclerView = activity.findViewById(R.id.recyclerview);
// This test assumes that the screen width and the height are different.
recyclerView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
recyclerView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutManager.setFlexDirection(FlexDirection.ROW);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
for (int i = 0; i < 100; i++) {
FlexboxLayoutManager.LayoutParams lp = createLayoutParams(activity, 90, 65);
adapter.addItem(lp);
}
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
FlexLine firstLine = layoutManager.getFlexLines().get(0);
assertThat(layoutManager.getFlexDirection(), is(FlexDirection.ROW));
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
GeneralLocation.TOP_CENTER));
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
GeneralLocation.TOP_CENTER));
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
int orientation = activity.getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
layoutManager.scrollToPosition(0);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
FlexLine firstLineAfterRotation = layoutManager.getFlexLines().get(0);
assertThat(firstLine.getMainSize(), is(not(firstLineAfterRotation.getMainSize())));
}
@Test
@FlakyTest
public void testFlexLinesDiscardedOnOrientationChange_direction_column() throws Throwable {
// Verifies the case that the calculated Flex lines are correctly discarded when a
// orientation
// happens with an Activity that handles configuration changes manually
final ConfigChangeActivity activity = mActivityRule.getActivity();
final FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(activity);
final TestAdapter adapter = new TestAdapter();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.setContentView(R.layout.recyclerview);
RecyclerView recyclerView = activity.findViewById(R.id.recyclerview);
// This test assumes that the screen width and the height are different.
recyclerView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
recyclerView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutManager.setFlexDirection(FlexDirection.COLUMN);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
for (int i = 0; i < 100; i++) {
FlexboxLayoutManager.LayoutParams lp = createLayoutParams(activity, 90, 65);
adapter.addItem(lp);
}
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
FlexLine firstLine = layoutManager.getFlexLines().get(0);
assertThat(layoutManager.getFlexDirection(), is(FlexDirection.COLUMN));
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
GeneralLocation.CENTER_LEFT));
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
GeneralLocation.CENTER_LEFT));
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
int orientation = activity.getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
mActivityRule.runOnUiThread(new Runnable() {
@Override
public void run() {
layoutManager.scrollToPosition(0);
}
});
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
FlexLine firstLineAfterRotation = layoutManager.getFlexLines().get(0);
assertThat(firstLine.getMainSize(), is(not(firstLineAfterRotation.getMainSize())));
}
/**
* Creates a new flex item.
*
* @param context the context
* @param width in DP
* @param height in DP
* @return the created {@link FlexboxLayoutManager.LayoutParams} instance
*/
private FlexboxLayoutManager.LayoutParams createLayoutParams(Context context, int width,
int height) {
return new FlexboxLayoutManager.LayoutParams(
TestUtil.dpToPixel(context, width),
TestUtil.dpToPixel(context, height));
}
private static ViewAction swipe(CoordinatesProvider from, CoordinatesProvider to) {
return new GeneralSwipeAction(Swipe.FAST, from, to, Press.FINGER);
}
}
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.support.test.InstrumentationRegistry
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.ViewAction
import android.support.test.espresso.action.*
import android.support.test.espresso.matcher.ViewMatchers.withId
import android.support.test.filters.FlakyTest
import android.support.test.filters.MediumTest
import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexboxLayoutManager
import org.hamcrest.Matchers.`is`
import org.hamcrest.core.IsNot.not
import org.junit.Assert.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
/**
* Integration tests for [FlexboxLayoutManager] with the Activity that handles configuration
* changes manually.
*/
@RunWith(AndroidJUnit4::class)
@MediumTest
class FlexboxLayoutManagerConfigChangeTest {
@JvmField
@Rule
var activityRule = ActivityTestRule(ConfigChangeActivity::class.java)
@Test
@FlakyTest
@Throws(Throwable::class)
fun testFlexLinesDiscardedOnOrientationChange_direction_row() {
// Verifies the case that the calculated Flex lines are correctly discarded when a
// orientation happens with an Activity that handles configuration changes manually
val activity = activityRule.activity
val layoutManager = FlexboxLayoutManager(activity)
val adapter = TestAdapter()
activityRule.runOnUiThread {
activity.setContentView(R.layout.recyclerview)
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
// This test assumes that the screen width and the height are different.
recyclerView.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
recyclerView.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
layoutManager.flexDirection = FlexDirection.ROW
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
for (i in 0..99) {
val lp = createLayoutParams(activity, 90, 65)
adapter.addItem(lp)
}
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
val firstLine = layoutManager.flexLines[0]
assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
GeneralLocation.TOP_CENTER))
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
GeneralLocation.TOP_CENTER))
activityRule.runOnUiThread {
val orientation = activity.resources.configuration.orientation
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
} else {
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
activityRule.runOnUiThread { layoutManager.scrollToPosition(0) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
val firstLineAfterRotation = layoutManager.flexLines[0]
assertThat(firstLine.mainSize, `is`(not(firstLineAfterRotation.mainSize)))
}
@Test
@FlakyTest
@Throws(Throwable::class)
fun testFlexLinesDiscardedOnOrientationChange_direction_column() {
// Verifies the case that the calculated Flex lines are correctly discarded when a
// orientation happens with an Activity that handles configuration changes manually
val activity = activityRule.activity
val layoutManager = FlexboxLayoutManager(activity)
val adapter = TestAdapter()
activityRule.runOnUiThread {
activity.setContentView(R.layout.recyclerview)
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
// This test assumes that the screen width and the height are different.
recyclerView.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
recyclerView.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
layoutManager.flexDirection = FlexDirection.COLUMN
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
for (i in 0..99) {
val lp = createLayoutParams(activity, 90, 65)
adapter.addItem(lp)
}
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
val firstLine = layoutManager.flexLines[0]
assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
GeneralLocation.CENTER_LEFT))
onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
GeneralLocation.CENTER_LEFT))
activityRule.runOnUiThread {
val orientation = activity.resources.configuration.orientation
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
} else {
activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
activityRule.runOnUiThread { layoutManager.scrollToPosition(0) }
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
val firstLineAfterRotation = layoutManager.flexLines[0]
assertThat(firstLine.mainSize, `is`(not(firstLineAfterRotation.mainSize)))
}
/**
* Creates a new flex item.
*
* @param context the context
* @param width in DP
* @param height in DP
* @return the created [FlexboxLayoutManager.LayoutParams] instance
*/
private fun createLayoutParams(context: Context, width: Int,
height: Int): FlexboxLayoutManager.LayoutParams {
return FlexboxLayoutManager.LayoutParams(context.dpToPixel(width), context.dpToPixel(height))
}
private fun swipe(from: CoordinatesProvider, to: CoordinatesProvider): ViewAction {
return GeneralSwipeAction(Swipe.FAST, from, to, Press.FINGER)
}
}
......@@ -14,15 +14,12 @@
* limitations under the License.
*/
package com.google.android.flexbox.test;
package com.google.android.flexbox.test
import com.google.android.flexbox.FlexboxLayout;
import android.app.Activity;
import android.app.Activity
import com.google.android.flexbox.FlexboxLayout
/**
* Activity for testing the {@link FlexboxLayout}.
* Activity for testing the [FlexboxLayout].
*/
public class FlexboxTestActivity extends Activity {
}
class FlexboxTestActivity : Activity()
......@@ -14,59 +14,38 @@
* limitations under the License.
*/
package com.google.android.flexbox.test;
package com.google.android.flexbox.test
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import java.util.Locale;
import org.hamcrest.BaseMatcher
import org.hamcrest.Description
import org.hamcrest.Factory
import org.hamcrest.Matcher
import java.util.*
/**
* Custom {@link BaseMatcher} that expects {@link Number} value allowing some errors to allow
* Custom [BaseMatcher] that expects [Number] value allowing some errors to allow
* such as rounding errors.
*/
public class IsEqualAllowingError<T extends Number> extends BaseMatcher<T> {
private Number expected;
private Integer errorAllowed;
private IsEqualAllowingError(Number expected) {
this(expected, 2);
}
class IsEqualAllowingError<T : Number> private constructor(private val expected: Number, private val errorAllowed: Int) : BaseMatcher<T>() {
private IsEqualAllowingError(Number expected, int errorAllowed) {
this.expected = expected;
this.errorAllowed = errorAllowed;
}
@Override
public boolean matches(Object item) {
if (!(item instanceof Number)) {
return false;
override fun matches(item: Any): Boolean {
if (item !is Number) {
return false
}
Number other = (Number) item;
return expected.intValue() - errorAllowed <= other.intValue() &&
other.intValue() <= expected.intValue() + errorAllowed;
return expected.toInt() - errorAllowed <= item.toInt() && item.toInt() <= expected.toInt() + errorAllowed
}
@Override
public void describeTo(Description description) {
override fun describeTo(description: Description) {
description.appendText(
String.format(Locale.US, "expected value is <%s> allowing error of <%s>.", expected,
errorAllowed));
errorAllowed))
}
@Factory
public static <T extends Number> Matcher<T> isEqualAllowingError(T expected) {
return new IsEqualAllowingError<>(expected);
}
companion object {
@Factory
public static <T extends Number> Matcher<T> isEqualAllowingError(T expected, int errorAllowed) {
return new IsEqualAllowingError<>(expected, errorAllowed);
@Factory
fun <T : Number> isEqualAllowingError(expected: T): Matcher<T> {
return IsEqualAllowingError(expected, 2)
}
}
}
......@@ -14,55 +14,33 @@
* limitations under the License.
*/
package com.google.android.flexbox.test;
package com.google.android.flexbox.test
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
/**
* Adapter for the tests for nested RecyclerViews.
* This Adapter is used for the inner RecyclerView.
*/
class NestedInnerAdapter extends RecyclerView.Adapter<NestedInnerAdapter.InnerViewHolder> {
internal class NestedInnerAdapter(private val innerPosition: Int, private val itemCount: Int) : RecyclerView.Adapter<NestedInnerAdapter.InnerViewHolder>() {
private int mInnerPosition;
private int mItemCount;
NestedInnerAdapter(int innerPosition, int itemCount) {
mInnerPosition = innerPosition;
mItemCount = itemCount;
}
@Override
public NestedInnerAdapter.InnerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.viewholder_textview, parent, false);
return new InnerViewHolder(view);
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NestedInnerAdapter.InnerViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.viewholder_textview, parent, false)
return InnerViewHolder(view)
}
@Override
public void onBindViewHolder(InnerViewHolder holder, int position) {
String description = holder.mTextView.getResources().getString(R.string.item_description);
holder.mTextView.setText(String.format(description, mInnerPosition, position));
override fun onBindViewHolder(holder: InnerViewHolder, position: Int) {
holder.textView.text = holder.textView.resources.getString(R.string.item_description, innerPosition, position)
}
@Override
public int getItemCount() {
return mItemCount;
}
static class InnerViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
override fun getItemCount() = itemCount
InnerViewHolder(View itemView) {
super(itemView);
internal class InnerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
mTextView = itemView.findViewById(R.id.textview);
}
val textView: TextView = itemView.findViewById(R.id.textview)
}
}
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexboxLayoutManager;
import java.util.ArrayList;
import java.util.List;
/**
* Adapter for the tests for nested RecyclerViews.
* This Adapter is used for the outer RecyclerView.
*/
class NestedOuterAdapter extends RecyclerView.Adapter<NestedOuterAdapter.OuterViewHolder> {
private static final int ITEM_COUNT = 4;
private final Context mContext;
private final List<OuterViewHolder> mViewHolderList = new ArrayList<>();
private final int mFlexDirection;
private final int mInnerAdapterItemCount;
private final int mViewHolderResId;
NestedOuterAdapter(Context context, @FlexDirection int flexDirection, int innerAdapterItemCount,
@LayoutRes int viewHolderResId) {
mContext = context;
mFlexDirection = flexDirection;
mInnerAdapterItemCount = innerAdapterItemCount;
mViewHolderResId = viewHolderResId;
}
@Override
public NestedOuterAdapter.OuterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(mViewHolderResId, parent, false);
OuterViewHolder holder = new OuterViewHolder(view);
mViewHolderList.add(holder);
return holder;
}
@Override
public void onBindViewHolder(OuterViewHolder holder, int position) {
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(mContext);
layoutManager.setFlexDirection(mFlexDirection);
holder.mInnerRecyclerView.setLayoutManager(layoutManager);
holder.mInnerRecyclerView.setAdapter(new NestedInnerAdapter(position,
mInnerAdapterItemCount));
}
OuterViewHolder getViewHolder(int position) {
return mViewHolderList.get(position);
}
@Override
public int getItemCount() {
return ITEM_COUNT;
}
static class OuterViewHolder extends RecyclerView.ViewHolder {
RecyclerView mInnerRecyclerView;
OuterViewHolder(View itemView) {
super(itemView);
mInnerRecyclerView = itemView.findViewById(R.id.recyclerview_inner);
}
}
}
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test
import android.support.annotation.LayoutRes
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexboxLayoutManager
/**
* Adapter for the tests for nested RecyclerViews.
* This Adapter is used for the outer RecyclerView.
*/
internal class NestedOuterAdapter(
@param:FlexDirection private val flexDirection: Int, private val innerAdapterItemCount: Int,
@param:LayoutRes private val viewHolderResId: Int
) : RecyclerView.Adapter<NestedOuterAdapter.OuterViewHolder>() {
private val viewHolderList = mutableListOf<OuterViewHolder>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OuterViewHolder {
val view = LayoutInflater.from(parent.context).inflate(viewHolderResId, parent, false)
val holder = OuterViewHolder(view)
viewHolderList.add(holder)
return holder
}
override fun onBindViewHolder(holder: OuterViewHolder, position: Int) {
val layoutManager = FlexboxLayoutManager(holder.itemView.context)
layoutManager.flexDirection = flexDirection
holder.innerRecyclerView.layoutManager = layoutManager
holder.innerRecyclerView.adapter = NestedInnerAdapter(position, innerAdapterItemCount)
}
fun getViewHolder(position: Int) = viewHolderList[position]
override fun getItemCount() = ITEM_COUNT
internal class OuterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val innerRecyclerView: RecyclerView = itemView.findViewById(R.id.recyclerview_inner)
}
companion object {
private const val ITEM_COUNT = 4
}
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.flexbox.FlexboxLayoutManager;
import java.util.ArrayList;
import java.util.List;
/**
* {@link RecyclerView.Adapter} implementation for {@link TestViewHolder}.
*/
class TestAdapter extends RecyclerView.Adapter<TestViewHolder> {
private List<FlexboxLayoutManager.LayoutParams> mLayoutParams;
private List<Object> mReceivedPayloads = new ArrayList<>();
TestAdapter() {
this(new ArrayList<FlexboxLayoutManager.LayoutParams>());
}
private TestAdapter(List<FlexboxLayoutManager.LayoutParams> flexItems) {
mLayoutParams = flexItems;
}
@Override
public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_viewholder, parent, false);
return new TestViewHolder(view);
}
@Override
public void onBindViewHolder(TestViewHolder holder, int position) {
holder.mTextView.setText(String.valueOf(position + 1));
holder.mTextView.setBackgroundResource(R.drawable.flex_item_background);
holder.mTextView.setGravity(Gravity.CENTER);
holder.mTextView.setLayoutParams(mLayoutParams.get(position));
}
@Override
public void onBindViewHolder(TestViewHolder holder, int position, List<Object> payloads) {
mReceivedPayloads.addAll(payloads);
onBindViewHolder(holder, position);
}
void addItem(int position, FlexboxLayoutManager.LayoutParams flexItem) {
mLayoutParams.add(position, flexItem);
notifyItemInserted(position);
}
void addItem(FlexboxLayoutManager.LayoutParams flexItem) {
mLayoutParams.add(flexItem);
notifyItemInserted(mLayoutParams.size() - 1);
}
void changeItemWithPayload(int position, Object payload) {
notifyItemChanged(position, payload);
}
List<Object> getPayloads() {
return new ArrayList<>(mReceivedPayloads);
}
FlexboxLayoutManager.LayoutParams getItemAt(int index) {
return mLayoutParams.get(index);
}
@Override
public int getItemCount() {
return mLayoutParams.size();
}
}
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test
import android.support.v7.widget.RecyclerView
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewGroup
import com.google.android.flexbox.FlexboxLayoutManager
/**
* [RecyclerView.Adapter] implementation for [TestViewHolder].
*/
internal class TestAdapter private constructor(private val layoutParams: MutableList<FlexboxLayoutManager.LayoutParams>) : RecyclerView.Adapter<TestViewHolder>() {
private val receivedPayloads = mutableListOf<Any>()
constructor() : this(mutableListOf<FlexboxLayoutManager.LayoutParams>())
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.recyclerview_viewholder, parent, false)
return TestViewHolder(view)
}
override fun onBindViewHolder(holder: TestViewHolder, position: Int) {
holder.textView.text = (position + 1).toString()
holder.textView.setBackgroundResource(R.drawable.flex_item_background)
holder.textView.gravity = Gravity.CENTER
holder.textView.layoutParams = layoutParams[position]
}
override fun onBindViewHolder(holder: TestViewHolder, position: Int, payloads: List<Any>?) {
payloads?.let(receivedPayloads::addAll)
onBindViewHolder(holder, position)
}
fun addItem(position: Int, flexItem: FlexboxLayoutManager.LayoutParams) {
layoutParams.add(position, flexItem)
notifyItemInserted(position)
}
fun addItem(flexItem: FlexboxLayoutManager.LayoutParams) {
layoutParams.add(flexItem)
notifyItemInserted(layoutParams.size - 1)
}
fun changeItemWithPayload(position: Int, payload: Any) {
notifyItemChanged(position, payload)
}
val payloads get() = receivedPayloads.toList()
fun getItemAt(index: Int) = layoutParams[index]
override fun getItemCount() = layoutParams.size
}
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.flexbox.FlexboxLayoutManager;
import java.util.ArrayList;
import java.util.List;
/**
* {@link RecyclerView.Adapter} implementation for {@link TestViewHolder}, which has multiple
* view types.
*/
class TestAdapterMultiViewTypes extends RecyclerView.Adapter<TestViewHolder> {
static final int POSITION_MATCH_PARENT = 3;
private static final int ITEMS = 50;
private static final int VIEW_TYPE_NORMAL = 0;
private static final int VIEW_TYPE_MATCH_PARENT = 1;
private final List<Item> mItems;
TestAdapterMultiViewTypes() {
mItems = new ArrayList<>();
for (int i = 0; i < ITEMS; i++) {
Item item = new Item();
if (i == POSITION_MATCH_PARENT) {
item.viewType = VIEW_TYPE_MATCH_PARENT;
}
item.value = i + 1;
mItems.add(item);
}
}
@Override
public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_viewholder, parent, false);
if (viewType == VIEW_TYPE_MATCH_PARENT) {
FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams)
view.getLayoutParams();
flexboxLp.setFlexBasisPercent(90f);
flexboxLp.setFlexGrow(1f);
}
return new TestViewHolder(view);
}
@Override
public void onBindViewHolder(TestViewHolder holder, int position) {
holder.mTextView.setText(String.valueOf(mItems.get(position).value));
holder.mTextView.setBackgroundResource(R.drawable.flex_item_background);
holder.mTextView.setGravity(Gravity.CENTER);
}
@Override
public int getItemViewType(int position) {
return mItems.get(position).viewType;
}
void addItemAt(int position, Item item) {
mItems.add(position, item);
notifyItemInserted(position);
}
@Override
public int getItemCount() {
return mItems.size();
}
static class Item {
int viewType = VIEW_TYPE_NORMAL;
int value;
}
}
/*
* Copyright 2017 Google Inc. All rights reserved.
*
* 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.google.android.flexbox.test
import android.support.v7.widget.RecyclerView
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewGroup
import com.google.android.flexbox.FlexboxLayoutManager
/**
* [RecyclerView.Adapter] implementation for [TestViewHolder], which has multiple
* view types.
*/
internal class TestAdapterMultiViewTypes : RecyclerView.Adapter<TestViewHolder>() {
private val items = mutableListOf<Item>()
init {
for (i in 0 until ITEMS) {
val item = Item()
if (i == POSITION_MATCH_PARENT) {
item.viewType = VIEW_TYPE_MATCH_PARENT
}
item.value = i + 1
items.add(item)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.recyclerview_viewholder, parent, false)
if (viewType == VIEW_TYPE_MATCH_PARENT) {
val flexboxLp = view.layoutParams as FlexboxLayoutManager.LayoutParams
flexboxLp.flexBasisPercent = 90f
flexboxLp.flexGrow = 1f
}
return TestViewHolder(view)
}
override fun onBindViewHolder(holder: TestViewHolder, position: Int) {
holder.textView.text = items[position].value.toString()
holder.textView.setBackgroundResource(R.drawable.flex_item_background)
holder.textView.gravity = Gravity.CENTER
}
override fun getItemViewType(position: Int) = items[position].viewType
fun addItemAt(position: Int, item: Item) {
items.add(position, item)
notifyItemInserted(position)
}
override fun getItemCount() = items.size
internal class Item {
internal var viewType = VIEW_TYPE_NORMAL
internal var value = 0
}
companion object {
internal val POSITION_MATCH_PARENT = 3
private val ITEMS = 50
private val VIEW_TYPE_NORMAL = 0
private val VIEW_TYPE_MATCH_PARENT = 1
}
}
......@@ -14,18 +14,11 @@
* limitations under the License.
*/
package com.google.android.flexbox.test;
package com.google.android.flexbox.test
import android.content.Context;
import android.util.DisplayMetrics;
import android.content.Context
/**
* Utility class for tests.
*/
class TestUtil {
static int dpToPixel(Context context, int dp) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return dp < 0 ? dp : Math.round(dp * displayMetrics.density);
}
internal fun Context.dpToPixel(dp: Int): Int {
val displayMetrics = this.resources.displayMetrics
return if (dp < 0) dp else Math.round(dp * displayMetrics.density)
}
......@@ -14,22 +14,15 @@
* limitations under the License.
*/
package com.google.android.flexbox.test;
package com.google.android.flexbox.test
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.TextView
/**
* ViewHolder implementation for a flex item for testing.
*/
class TestViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
TestViewHolder(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.textview);
}
internal class TestViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView: TextView = itemView.findViewById(R.id.textview)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册