Merge "Add internal TestViewConfiguration" into androidx-main
diff --git a/compose/foundation/foundation/build.gradle b/compose/foundation/foundation/build.gradle
index 7d4b5d7..ca1170a 100644
--- a/compose/foundation/foundation/build.gradle
+++ b/compose/foundation/foundation/build.gradle
@@ -48,7 +48,7 @@
         implementation(project(":compose:ui:ui-text"))
         implementation(project(":compose:ui:ui-util"))
 
-
+        testImplementation(project(":compose:test-utils"))
         testImplementation(ANDROIDX_TEST_RULES)
         testImplementation(ANDROIDX_TEST_RUNNER)
         testImplementation(JUNIT)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
index 3ba18ed..c0abd58 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
@@ -36,12 +36,12 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
+import androidx.compose.testutils.WithTouchSlop
 import androidx.compose.testutils.assertIsEqualTo
 import androidx.compose.testutils.assertPixels
 import androidx.compose.testutils.runBlockingWithManualClock
@@ -51,8 +51,6 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.platform.LocalViewConfiguration
-import androidx.compose.ui.platform.ViewConfiguration
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.SemanticsNodeInteraction
@@ -1407,26 +1405,13 @@
     isIn(Range.closed(expected - tolerance, expected + tolerance))
 }
 
-internal val TestTouchSlop = 18f
-
-private val FakeViewConfiguration = object : ViewConfiguration {
-    override val longPressTimeoutMillis: Long
-        get() = 500L
-    override val doubleTapTimeoutMillis: Long
-        get() = 300L
-    override val doubleTapMinTimeMillis: Long
-        get() = 40L
-    override val touchSlop: Float
-        get() = TestTouchSlop
-}
+internal const val TestTouchSlop = 18f
 
 internal fun ComposeContentTestRule.setContentWithTestViewConfiguration(
     composable: @Composable () -> Unit
 ) {
     this.setContent {
-        CompositionLocalProvider(LocalViewConfiguration provides FakeViewConfiguration) {
-            composable()
-        }
+        WithTouchSlop(TestTouchSlop, composable)
     }
 }
 
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/SuspendingGestureTestUtil.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/SuspendingGestureTestUtil.kt
index 27ba0c3..48f0ef9 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/SuspendingGestureTestUtil.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/gestures/SuspendingGestureTestUtil.kt
@@ -19,13 +19,14 @@
 import androidx.compose.runtime.Applier
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composer
-import androidx.compose.runtime.InternalComposeApi
 import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.Recomposer
 import androidx.compose.runtime.ControlledComposition
-import androidx.compose.runtime.currentComposer
+import androidx.compose.runtime.InternalComposeApi
 import androidx.compose.runtime.MonotonicFrameClock
+import androidx.compose.runtime.Recomposer
+import androidx.compose.runtime.currentComposer
 import androidx.compose.runtime.withRunningRecomposer
+import androidx.compose.testutils.TestViewConfiguration
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.input.pointer.ConsumedData
@@ -39,7 +40,6 @@
 import androidx.compose.ui.materialize
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalViewConfiguration
-import androidx.compose.ui.platform.ViewConfiguration
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.IntSize
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -346,18 +346,4 @@
         }
         override fun clear() {}
     }
-
-    private class TestViewConfiguration : ViewConfiguration {
-        override val longPressTimeoutMillis: Long
-            get() = 500
-
-        override val doubleTapTimeoutMillis: Long
-            get() = 300
-
-        override val doubleTapMinTimeMillis: Long
-            get() = 40
-
-        override val touchSlop: Float
-            get() = 18f
-    }
 }
\ No newline at end of file
diff --git a/compose/test-utils/src/commonMain/kotlin/androidx/compose/testutils/TestViewConfiguration.kt b/compose/test-utils/src/commonMain/kotlin/androidx/compose/testutils/TestViewConfiguration.kt
new file mode 100644
index 0000000..64f01f6
--- /dev/null
+++ b/compose/test-utils/src/commonMain/kotlin/androidx/compose/testutils/TestViewConfiguration.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * 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 androidx.compose.testutils
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.platform.LocalViewConfiguration
+import androidx.compose.ui.platform.ViewConfiguration
+
+/**
+ * A [ViewConfiguration] that can be used for testing. The default values are representative for
+ * Android devices, but can be set to any value desired for a test. See the `With*` functions for
+ * shorthands that create a [TestViewConfiguration] and provide it as a [LocalViewConfiguration].
+ *
+ * @see WithLongPressTimeoutMillis
+ * @see WithDoubleTapTimeoutMillis
+ * @see WithDoubleTapMinTimeMillis
+ * @see WithTouchSlop
+ */
+class TestViewConfiguration(
+    override val longPressTimeoutMillis: Long = 500L,
+    override val doubleTapTimeoutMillis: Long = 300L,
+    override val doubleTapMinTimeMillis: Long = 40L,
+    override val touchSlop: Float = 18f
+) : ViewConfiguration
+
+@Composable
+fun WithLongPressTimeoutMillis(longPressTimeoutMillis: Long, content: @Composable () -> Unit) {
+    WithViewConfiguration(
+        TestViewConfiguration(longPressTimeoutMillis = longPressTimeoutMillis),
+        content = content
+    )
+}
+
+@Composable
+fun WithDoubleTapTimeoutMillis(doubleTapTimeoutMillis: Long, content: @Composable () -> Unit) {
+    WithViewConfiguration(
+        TestViewConfiguration(doubleTapTimeoutMillis = doubleTapTimeoutMillis),
+        content = content
+    )
+}
+
+@Composable
+fun WithDoubleTapMinTimeMillis(doubleTapMinTimeMillis: Long, content: @Composable () -> Unit) {
+    WithViewConfiguration(
+        TestViewConfiguration(doubleTapMinTimeMillis = doubleTapMinTimeMillis),
+        content = content
+    )
+}
+
+@Composable
+fun WithTouchSlop(touchSlop: Float, content: @Composable () -> Unit) {
+    WithViewConfiguration(
+        TestViewConfiguration(touchSlop = touchSlop),
+        content = content
+    )
+}
+
+@Composable
+fun WithViewConfiguration(
+    testViewConfiguration: TestViewConfiguration,
+    content: @Composable () -> Unit
+) {
+    CompositionLocalProvider(
+        LocalViewConfiguration provides testViewConfiguration,
+        content = content
+    )
+}
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt
index e01eadf..2fa7c14 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt
@@ -24,14 +24,12 @@
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.testutils.WithTouchSlop
 import androidx.compose.testutils.expectError
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalViewConfiguration
-import androidx.compose.ui.platform.ViewConfiguration
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.ExperimentalTestApi
 import androidx.compose.ui.test.bottomCenter
@@ -266,10 +264,10 @@
 
     @Test
     fun swipeScrollable() {
-        val touchSlop = TestTouchSlop
+        val touchSlop = 18f
         val scrollState = ScrollState(initial = 0)
         rule.setContent {
-            CompositionLocalProvider(LocalViewConfiguration provides FakeViewConfiguration) {
+            WithTouchSlop(touchSlop) {
                 with(LocalDensity.current) {
                     // Scrollable with a viewport the size of 10 boxes
                     Column(
@@ -345,17 +343,4 @@
         events.map { it.position.x }.assertIncreasing()
         events.map { it.position.y }.assertSame(tolerance = 0.001f)
     }
-
-    internal val TestTouchSlop = 18f
-
-    private val FakeViewConfiguration = object : ViewConfiguration {
-        override val longPressTimeoutMillis: Long
-            get() = 500L
-        override val doubleTapTimeoutMillis: Long
-            get() = 300L
-        override val doubleTapMinTimeMillis: Long
-            get() = 40L
-        override val touchSlop: Float
-            get() = TestTouchSlop
-    }
 }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
index 9046500..49c2c27 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
@@ -22,11 +22,11 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshots.Snapshot
+import androidx.compose.testutils.TestViewConfiguration
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.platform.InspectableValue
 import androidx.compose.ui.platform.ValueElement
-import androidx.compose.ui.platform.ViewConfiguration
 import androidx.compose.ui.platform.isDebugInspectorInfoEnabled
 import androidx.compose.ui.test.TestActivity
 import androidx.compose.ui.unit.IntSize
@@ -68,7 +68,7 @@
 
     @Test
     fun testAwaitSingleEvent(): Unit = runBlockingTest {
-        val filter = SuspendingPointerInputFilter(FakeViewConfiguration())
+        val filter = SuspendingPointerInputFilter(TestViewConfiguration())
 
         val result = CompletableDeferred<PointerEvent>()
         launch {
@@ -97,7 +97,7 @@
 
     @Test
     fun testAwaitSeveralEvents(): Unit = runBlockingTest {
-        val filter = SuspendingPointerInputFilter(FakeViewConfiguration())
+        val filter = SuspendingPointerInputFilter(TestViewConfiguration())
         val results = Channel<PointerEvent>(Channel.UNLIMITED)
         launch {
             with(filter) {
@@ -132,7 +132,7 @@
 
     @Test
     fun testSyntheticCancelEvent(): Unit = runBlockingTest {
-        val filter = SuspendingPointerInputFilter(FakeViewConfiguration())
+        val filter = SuspendingPointerInputFilter(TestViewConfiguration())
         val results = Channel<PointerEvent>(Channel.UNLIMITED)
         launch {
             with(filter) {
@@ -200,7 +200,7 @@
 
     @Test
     fun testCancelledHandlerBlock() = runBlockingTest {
-        val filter = SuspendingPointerInputFilter(FakeViewConfiguration())
+        val filter = SuspendingPointerInputFilter(TestViewConfiguration())
         val counter = TestCounter()
         val handler = launch {
             with(filter) {
@@ -305,17 +305,6 @@
     }
 }
 
-private class FakeViewConfiguration : ViewConfiguration {
-    override val longPressTimeoutMillis: Long
-        get() = 500
-    override val doubleTapTimeoutMillis: Long
-        get() = 300
-    override val doubleTapMinTimeMillis: Long
-        get() = 40
-    override val touchSlop: Float
-        get() = 18f
-}
-
 private class TestCounter {
     private var count = 0