[go: nahoru, domu]

Adding AndroidCraneViewTest with autofill tests

Bug: 139314168
Test: Ran the tests on emulators for API levels < 26 and > 26.
Change-Id: Ia388e448ffb1106e33a958a37f681e748dc67d5b
diff --git a/ui/ui-platform/src/androidTest/AndroidManifest.xml b/ui/ui-platform/src/androidTest/AndroidManifest.xml
index f086f11..ce716e4 100644
--- a/ui/ui-platform/src/androidTest/AndroidManifest.xml
+++ b/ui/ui-platform/src/androidTest/AndroidManifest.xml
@@ -14,9 +14,9 @@
      limitations under the License.
 -->
 <manifest package="androidx.ui.platform" xmlns:android="http://schemas.android.com/apk/res/android">
-
     <application>
-        <activity android:name="androidx.ui.platform.test.TestActivity" android:theme="@android:style/Theme.Material.NoActionBar.Fullscreen"/>
+        <activity android:name="android.app.Activity"
+                  android:theme="@android:style/Theme.Material.NoActionBar.Fullscreen"/>
     </application>
 </manifest>
 
diff --git a/ui/ui-platform/src/androidTest/java/androidx/ui/core/AndroidCraneViewTest.kt b/ui/ui-platform/src/androidTest/java/androidx/ui/core/AndroidCraneViewTest.kt
new file mode 100644
index 0000000..09cec49
--- /dev/null
+++ b/ui/ui-platform/src/androidTest/java/androidx/ui/core/AndroidCraneViewTest.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2019 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.ui.core
+
+import android.app.Activity
+import android.graphics.Rect
+import android.util.SparseArray
+import android.view.View
+import android.view.ViewStructure
+import android.view.autofill.AutofillValue
+import androidx.test.filters.SdkSuppress
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.autofill.AndroidAutofill
+import androidx.ui.autofill.AutofillNode
+import androidx.ui.autofill.AutofillType
+import androidx.ui.test.android.fake.FakeViewStructure
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class AndroidCraneViewTest {
+    @get:Rule
+    val activityTestRule = ActivityTestRule<Activity>(Activity::class.java)
+
+    private val PACKAGE_NAME = "androidx.ui.platform.test"
+    private lateinit var craneView: AndroidCraneView
+
+    @Before
+    fun setup() {
+        craneView = AndroidCraneView(activityTestRule.activity)
+    }
+
+    @SdkSuppress(maxSdkVersion = 25)
+    @Test
+    fun autofillAmbient_belowApi26_isNull() {
+        assertThat(craneView.autofill).isNull()
+    }
+
+    @SdkSuppress(minSdkVersion = 26)
+    @Test
+    fun autofillAmbient_isNotNull() {
+        assertThat(craneView.autofill).isNotNull()
+    }
+
+    @SdkSuppress(minSdkVersion = 26)
+    @Test
+    fun autofillAmbient_returnsAnInstanceOfAndroidAutofill() {
+        assertThat(craneView.autofill).isInstanceOf(AndroidAutofill::class.java)
+    }
+
+    @SdkSuppress(minSdkVersion = 26)
+    @Test
+    fun onProvideAutofillVirtualStructure_populatesViewStructure() {
+        // Arrange.
+        val viewStructure: ViewStructure = FakeViewStructure()
+        val autofillNode = AutofillNode(
+            >
+            autofillTypes = listOf(AutofillType.Name),
+            boundingBox = Rect(0, 0, 0, 0)
+        )
+        craneView.autofillTree += autofillNode
+
+        // Act.
+        craneView.onProvideAutofillVirtualStructure(viewStructure, 0)
+
+        // Assert.
+        assertThat(viewStructure).isEqualTo(FakeViewStructure().apply {
+            children.add(FakeViewStructure().apply {
+                virtualId = autofillNode.id
+                packageName = PACKAGE_NAME
+                setAutofillType(View.AUTOFILL_TYPE_TEXT)
+                setAutofillHints(arrayOf(View.AUTOFILL_HINT_NAME))
+                setDimens(0, 0, 0, 0, 0, 0)
+            })
+        })
+    }
+
+    @SdkSuppress(minSdkVersion = 26)
+    @Test
+    fun autofill_triggersOnFill() {
+        // Arrange.
+        val expectedValue = "Name"
+        var autofilledValue = ""
+        val autofillNode = AutofillNode(
+             autofilledValue = it },
+            autofillTypes = listOf(AutofillType.Name),
+            boundingBox = Rect(0, 0, 0, 0)
+        )
+        val autofillValues = SparseArray<AutofillValue>().apply {
+            append(autofillNode.id, AutofillValue.forText(expectedValue))
+        }
+        craneView.autofillTree += autofillNode
+
+        // Act.
+        craneView.autofill(autofillValues)
+
+        // Assert.
+        assertThat(autofilledValue).isEqualTo(expectedValue)
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
index 456c958..fe51144 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
@@ -81,8 +81,8 @@
     // Map from model to LayoutNodes that *only* need layout and not measure
     private val relayoutOnly = ObserverMap<Any, LayoutNode>()
 
-    // TODO: Replace with SemanticsTree.
-    //  This is a temporary hack until we have a semantics tree implemented.
+    // Used by components that want to provide autofill semantic information.
+    // TODO: Replace with SemanticsTree: Temporary hack until we have a semantics tree implemented.
     val autofillTree = AutofillTree()
 
     // RepaintBoundaryNodes that have had their boundary changed. When using Views,
@@ -101,7 +101,7 @@
 
     var constraints = Constraints.tightConstraints(width = IntPx.Zero, height = IntPx.Zero)
     // TODO(mount): reinstate when coroutines are supported by IR compiler
-//    private val ownerScope = CoroutineScope(Dispatchers.Main.immediate + Job())
+    // private val ownerScope = CoroutineScope(Dispatchers.Main.immediate + Job())
 
     // Used for tracking which nodes a frame read is applied to
     internal var currentNode: ComponentNode? = null
@@ -112,6 +112,8 @@
     var configurationChangeObserver: () -> Unit = {}
 
     private val _autofill = if (autofillSupported()) AndroidAutofill(this, autofillTree) else null
+
+    // Used as an ambient for performing autofill.
     val autofill: Autofill? get() = _autofill
 
     override var measureIteration: Long = 1L
@@ -179,17 +181,17 @@
 
     override fun onInvalidate(drawNode: DrawNode) {
         // TODO(mount): use ownerScope. This isn't supported by IR compiler yet
-//        ownerScope.launch {
+        // ownerScope.launch {
         invalidateRepaintBoundary(drawNode)
-//        }
+        // }
     }
 
     override fun onSizeChange(layoutNode: LayoutNode) {
         // TODO(mount): use ownerScope. This isn't supported by IR compiler yet
-//        ownerScope.launch {
+        // ownerScope.launch {
         layoutNode.visitChildren(::collectChildrenRepaintBoundaries)
         invalidateRepaintBoundary(layoutNode)
-//        }
+        // }
     }
 
     /**
@@ -213,9 +215,9 @@
 
     override fun onPositionChange(layoutNode: LayoutNode) {
         // TODO(mount): use ownerScope. This isn't supported by IR compiler yet
-//        ownerScope.launch {
+        // ownerScope.launch {
         invalidateRepaintBoundary(layoutNode)
-//        }
+        // }
     }
 
     override fun onRepaintBoundaryParamsChange(repaintBoundaryNode: RepaintBoundaryNode) {
diff --git a/ui/ui-platform/src/test/java/androidx/ui/ComposeUiRobolectricTestRunner.kt b/ui/ui-platform/src/test/java/androidx/ui/ComposeUiRobolectricTestRunner.kt
new file mode 100644
index 0000000..32f660f
--- /dev/null
+++ b/ui/ui-platform/src/test/java/androidx/ui/ComposeUiRobolectricTestRunner.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 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.ui
+
+import org.junit.runners.model.FrameworkMethod
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.internal.bytecode.InstrumentationConfiguration
+
+/**
+ * A [RobolectricTestRunner] for [androidx.ui].
+ *
+ * It has instrumentation turned off for the [androidx.ui] package.
+ *
+ * Robolectric tries to instrument Kotlin classes, and it throws errors when it encounters
+ * companion objects and constructors with default values for parameters. We don't need
+ * shadowing of our classes because we want to use the actual objects in our tests.
+ *
+ * We can also make the argument that no external developer should shadow any of androidx.ui, as
+ * they shouldn't be testing library code. This concern is being tracked by b/139828620 which will
+ * make a change to Robolectric code to prevent instrumentation of all classes under [androidx.ui].
+ */
+class ComposeUiRobolectricTestRunner(testClass: Class<*>) : RobolectricTestRunner(testClass) {
+    override fun createClassLoaderConfig(method: FrameworkMethod?): InstrumentationConfiguration {
+        val builder = InstrumentationConfiguration.Builder(super.createClassLoaderConfig(method))
+        builder.doNotInstrumentPackage("androidx.ui")
+        return builder.build()
+    }
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidAutofillTest.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidAutofillTest.kt
index a135080..553974f 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidAutofillTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidAutofillTest.kt
@@ -16,65 +16,72 @@
 
 package androidx.ui.autofill
 
-import android.content.Context
+import android.app.Activity
 import android.graphics.Rect
 import android.view.View
 import android.view.autofill.AutofillManager
 import androidx.test.filters.SmallTest
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
+import androidx.ui.ComposeUiRobolectricTestRunner
+import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.ExpectedException
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
+import org.robolectric.Robolectric
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.Implementation
+import org.robolectric.annotation.Implements
+import org.robolectric.shadow.api.Shadow
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(ComposeUiRobolectricTestRunner::class)
+@Config(
+    manifest = Config.NONE,
+    shadows = [ShadowAutofillManager::class],
+    minSdk = 26
+)
 class AndroidAutofillTest {
 
     @get:Rule
     val expectedException = ExpectedException.none()!!
 
     private lateinit var androidAutofill: AndroidAutofill
-    private lateinit var autofillManager: AutofillManager
+    private lateinit var autofillManager: ShadowAutofillManager
     private lateinit var view: View
     private val autofillTree = AutofillTree()
 
     @Before
     fun setup() {
-        autofillManager = mock()
+        val activity = Robolectric.setupActivity(Activity::class.java)
+        view = View(activity)
+        activity.setContentView(view)
 
-        val context: Context = mock()
-        whenever(context.getSystemService(eq(AutofillManager::class.java)))
-            .thenReturn(autofillManager)
-
-        view = mock()
-        whenever(view.context).thenReturn(context)
+        autofillManager = Shadow.extract<ShadowAutofillManager>(
+            activity.getSystemService(AutofillManager::class.java)
+        )
 
         androidAutofill = AndroidAutofill(view, autofillTree)
     }
 
     @Test
     fun importantForAutofill_is_yes() {
-        verify(view).setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES)
+        assertThat(view.importantForAutofill).isEqualTo(View.IMPORTANT_FOR_AUTOFILL_YES)
     }
 
     @Test
     fun requestAutofillForNode_calls_notifyViewEntered() {
         // Arrange.
-        val autofillNode = AutofillNode( boundingBox = Rect(0, 0, 0, 0))
+        val bounds = Rect(0, 0, 0, 0)
+        val autofillNode = AutofillNode( boundingBox = bounds)
 
         // Act.
         androidAutofill.requestAutofillForNode(autofillNode)
 
         // Assert.
-        verify(autofillManager, times(1))
-            .notifyViewEntered(view, autofillNode.id, autofillNode.boundingBox!!)
+        assertThat(autofillManager.viewEnteredStats).containsExactly(
+            ShadowAutofillManager.NotifyViewEntered(view, autofillNode.id, bounds)
+        )
     }
 
     @Test
@@ -98,6 +105,27 @@
         androidAutofill.cancelAutofillForNode(autofillNode)
 
         // Assert.
-        verify(autofillManager, times(1)).notifyViewExited(view, autofillNode.id)
+        assertThat(autofillManager.viewExitedStats).containsExactly(
+            ShadowAutofillManager.NotifyViewExited(view, autofillNode.id)
+        )
+    }
+}
+
+@Implements(value = AutofillManager::class, minSdk = 26)
+internal class ShadowAutofillManager {
+    data class NotifyViewEntered(val view: View, val virtualId: Int, val rect: Rect)
+    data class NotifyViewExited(val view: View, val virtualId: Int)
+
+    val viewEnteredStats = mutableListOf<NotifyViewEntered>()
+    val viewExitedStats = mutableListOf<NotifyViewExited>()
+
+    @Implementation
+    fun notifyViewEntered(view: View, virtualId: Int, rect: Rect) {
+        viewEnteredStats += NotifyViewEntered(view, virtualId, rect)
+    }
+
+    @Implementation
+    fun notifyViewExited(view: View, virtualId: Int) {
+        viewExitedStats += NotifyViewExited(view, virtualId)
     }
 }
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidFakes.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidFakes.kt
deleted file mode 100644
index 0d539e3..0000000
--- a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidFakes.kt
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright 2019 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.ui.autofill
-
-import android.graphics.Matrix
-import android.graphics.Rect
-import android.os.Bundle
-import android.os.LocaleList
-import android.util.SparseArray
-import android.view.View
-import android.view.ViewStructure
-import android.view.autofill.AutofillId
-import android.view.autofill.AutofillValue
-import com.nhaarman.mockitokotlin2.mock
-
-/**
- * A fake implementation of { SparseArray } to use in tests.
- */
-internal class FakeSparseArray : SparseArray<AutofillValue>() {
-
-    private val map = mutableMapOf<Int, AutofillValue>()
-
-    override fun append(key: Int, value: AutofillValue?) {
-        value?.let { map.putIfAbsent(key, it) }
-    }
-
-    override fun size() = map.count()
-
-    override fun keyAt(index: Int) = map.asSequence().elementAt(index).component1()
-
-    override fun get(key: Int) = map[key] ?: error("no element for the specified key")
-}
-
-/**
- * A fake implementation of { ViewStructure } to use in tests.
- */
-internal data class FakeViewStructure(
-    var virtualId: Int = 0,
-    var packageName: String? = null,
-    var typeName: String? = null,
-    var entryName: String? = null,
-    var children: MutableList<FakeViewStructure> = mutableListOf(),
-    var bounds: Rect? = null,
-    private val autofillId: AutofillId? = mock(),
-    private var autofillType: Int = View.AUTOFILL_TYPE_NONE,
-    private var autofillHints: Array<out String> = arrayOf()
-) : ViewStructure() {
-
-    override fun getChildCount() = children.count()
-
-    override fun addChildCount(childCount: Int): Int {
-        repeat(childCount) { children.add(FakeViewStructure()) }
-        return children.count() - childCount
-    }
-
-    override fun newChild(index: Int): FakeViewStructure {
-        if (index >= children.count()) error("Call addChildCount() before calling newChild()")
-        return children[index]
-    }
-
-    override fun getAutofillId() = autofillId
-
-    override fun setAutofillId(rootId: AutofillId, virtualId: Int) {
-        this.virtualId = virtualId
-    }
-
-    override fun setId(
-        virtualId: Int,
-        packageName: String?,
-        typeName: String?,
-        entryName: String?
-    ) {
-        this.virtualId = virtualId
-        this.packageName = packageName
-        this.typeName = typeName
-        this.entryName = entryName
-    }
-
-    override fun setAutofillType(autofillType: Int) {
-        this.autofillType = autofillType
-    }
-
-    override fun setAutofillHints(autofillHints: Array<out String>?) {
-        autofillHints?.let { this.autofillHints = it }
-    }
-
-    override fun setDimens(left: Int, top: Int, x: Int, y: Int, width: Int, height: Int) {
-        this.bounds = Rect(left, top, width - left, height - top)
-    }
-
-    override fun equals(other: Any?) = other is FakeViewStructure &&
-            other.virtualId == virtualId &&
-            other.packageName == packageName &&
-            other.typeName == typeName &&
-            other.entryName == entryName &&
-            other.autofillType == autofillType &&
-            other.autofillHints.contentEquals(autofillHints) &&
-            other.bounds.contentEquals(bounds) &&
-            other.children == children
-
-    override fun hashCode() = super.hashCode()
-
-    // Unimplemented methods.
-
-    override fun setOpaque(p0: Boolean) { TODO("not implemented") }
-
-    override fun setHint(p0: CharSequence?) { TODO("not implemented") }
-
-    override fun setElevation(p0: Float) { TODO("not implemented") }
-
-    override fun getText(): CharSequence { TODO("not implemented") }
-
-    override fun setText(p0: CharSequence?) { TODO("not implemented") }
-
-    override fun setText(p0: CharSequence?, p1: Int, p2: Int) { TODO("not implemented") }
-
-    override fun asyncCommit() { TODO("not implemented") }
-
-    override fun setEnabled(p0: Boolean) { TODO("not implemented") }
-
-    override fun setLocaleList(p0: LocaleList?) { TODO("not implemented") }
-
-    override fun setChecked(p0: Boolean) { TODO("not implemented") }
-
-    override fun setContextClickable(p0: Boolean) { TODO("not implemented") }
-
-    override fun setAccessibilityFocused(p0: Boolean) { TODO("not implemented") }
-
-    override fun setAlpha(p0: Float) { TODO("not implemented") }
-
-    override fun setTransformation(p0: Matrix?) { TODO("not implemented") }
-
-    override fun setClassName(p0: String?) { TODO("not implemented") }
-
-    override fun setLongClickable(p0: Boolean) { TODO("not implemented") }
-
-    override fun getHint(): CharSequence { TODO("not implemented") }
-
-    override fun setInputType(p0: Int) { TODO("not implemented") }
-
-    override fun setWebDomain(p0: String?) { TODO("not implemented") }
-
-    override fun setAutofillOptions(p0: Array<out CharSequence>?) { TODO("not implemented") }
-
-    override fun setTextStyle(p0: Float, p1: Int, p2: Int, p3: Int) { TODO("not implemented") }
-
-    override fun setVisibility(p0: Int) { TODO("not implemented") }
-
-    override fun setHtmlInfo(p0: HtmlInfo) { TODO("not implemented") }
-
-    override fun setTextLines(p0: IntArray?, p1: IntArray?) { TODO("not implemented") }
-
-    override fun getExtras(): Bundle { TODO("not implemented") }
-
-    override fun setClickable(p0: Boolean) { TODO("not implemented") }
-
-    override fun newHtmlInfoBuilder(p0: String): HtmlInfo.Builder { TODO("not implemented") }
-
-    override fun getTextSelectionEnd(): Int { TODO("not implemented") }
-
-    override fun setAutofillId(p0: AutofillId) { TODO("not implemented") }
-
-    override fun hasExtras(): Boolean { TODO("not implemented") }
-
-    override fun setActivated(p0: Boolean) { TODO("not implemented") }
-
-    override fun setFocused(p0: Boolean) { TODO("not implemented") }
-
-    override fun getTextSelectionStart(): Int { TODO("not implemented") }
-
-    override fun setChildCount(p0: Int) { TODO("not implemented") }
-
-    override fun setAutofillValue(p0: AutofillValue?) { TODO("not implemented") }
-
-    override fun setContentDescription(p0: CharSequence?) { TODO("not implemented") }
-
-    override fun setFocusable(p0: Boolean) { TODO("not implemented") }
-
-    override fun setCheckable(p0: Boolean) { TODO("not implemented") }
-
-    override fun asyncNewChild(p0: Int): ViewStructure { TODO("not implemented") }
-
-    override fun setSelected(p0: Boolean) { TODO("not implemented") }
-
-    override fun setDataIsSensitive(p0: Boolean) { TODO("not implemented") }
-}
-
-private fun Rect?.contentEquals(other: Rect?) = when {
-    (other == null && this == null) -> true
-    (other == null || this == null) -> false
-    else -> other.left == left &&
-            other.right == right &&
-            other.bottom == bottom &&
-            other.top == top
-}
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPerformAutofillTest.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPerformAutofillTest.kt
index 6acec9c..f559223 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPerformAutofillTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPerformAutofillTest.kt
@@ -16,38 +16,34 @@
 
 package androidx.ui.autofill
 
-import android.content.Context
+import android.app.Activity
 import android.graphics.Rect
+import android.util.SparseArray
 import android.view.View
-import android.view.autofill.AutofillManager
 import android.view.autofill.AutofillValue
 import androidx.test.filters.SmallTest
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.times
-import com.nhaarman.mockitokotlin2.verify
-import com.nhaarman.mockitokotlin2.whenever
+import androidx.ui.ComposeUiRobolectricTestRunner
+import com.google.common.truth.Truth
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
+import org.robolectric.Robolectric
+import org.robolectric.annotation.Config
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(ComposeUiRobolectricTestRunner::class)
+@Config(
+    manifest = Config.NONE,
+    minSdk = 26)
 class AndroidPerformAutofillTest {
     private val autofillTree = AutofillTree()
     private lateinit var androidAutofill: AndroidAutofill
 
     @Before
     fun setup() {
-        val autofillManager: AutofillManager = mock()
-
-        val context: Context = mock()
-        whenever(context.getSystemService(eq(AutofillManager::class.java)))
-            .thenReturn(autofillManager)
-
-        val view: View = mock()
-        whenever(view.context).thenReturn(context)
+        val activity = Robolectric.setupActivity(Activity::class.java)
+        val view = View(activity)
+        activity.setContentView(view)
 
         androidAutofill = AndroidAutofill(view, autofillTree)
     }
@@ -55,48 +51,44 @@
     @Test
     fun performAutofill_name() {
         // Arrange.
-        val onFill: (String) -> Unit = mock()
+        val expectedValue = "First Name"
+        var autofilledValue = ""
         val autofillNode = AutofillNode(
-            >
+             autofilledValue = it },
             autofillTypes = listOf(AutofillType.Name),
             boundingBox = Rect(0, 0, 0, 0)
         )
         autofillTree += autofillNode
 
-        val autofillValue: AutofillValue = mock()
-        whenever(autofillValue.isText).thenReturn(true)
-        whenever(autofillValue.textValue).thenReturn("First Name")
-
-        val autofillValues = FakeSparseArray().apply { append(autofillNode.id, autofillValue) }
+        val autofillValues = SparseArray<AutofillValue>()
+            .apply { append(autofillNode.id, AutofillValue.forText(expectedValue)) }
 
         // Act.
         androidAutofill.performAutofill(autofillValues)
 
         // Assert.
-        verify(onFill, times(1)).invoke("First Name")
+        Truth.assertThat(autofilledValue).isEqualTo(expectedValue)
     }
 
     @Test
     fun performAutofill_email() {
         // Arrange.
-        val onFill: (String) -> Unit = mock()
+        val expectedValue = "email@google.com"
+        var autofilledValue = ""
         val autofillNode = AutofillNode(
-            >
+             autofilledValue = it },
             autofillTypes = listOf(AutofillType.EmailAddress),
             boundingBox = Rect(0, 0, 0, 0)
         )
         autofillTree += autofillNode
 
-        val autofillValue: AutofillValue = mock()
-        whenever(autofillValue.isText).thenReturn(true)
-        whenever(autofillValue.textValue).thenReturn("email@google.com")
-
-        val autofillValues = FakeSparseArray().apply { append(autofillNode.id, autofillValue) }
+        val autofillValues = SparseArray<AutofillValue>()
+            .apply { append(autofillNode.id, AutofillValue.forText(expectedValue)) }
 
         // Act.
         androidAutofill.performAutofill(autofillValues)
 
         // Assert.
-        verify(onFill, times(1)).invoke("email@google.com")
+        Truth.assertThat(autofilledValue).isEqualTo(expectedValue)
     }
 }
\ No newline at end of file
diff --git a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPopulateViewStructureTest.kt b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPopulateViewStructureTest.kt
index db8c641..9071352 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPopulateViewStructureTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/autofill/AndroidPopulateViewStructureTest.kt
@@ -16,38 +16,35 @@
 
 package androidx.ui.autofill
 
-import android.content.Context
+import android.app.Activity
 import android.graphics.Rect
 import android.view.View
 import android.view.ViewStructure
-import android.view.autofill.AutofillManager
 import androidx.test.filters.SmallTest
+import androidx.ui.ComposeUiRobolectricTestRunner
+import androidx.ui.test.android.fake.FakeViewStructure
 import com.google.common.truth.Truth.assertThat
-import com.nhaarman.mockitokotlin2.eq
-import com.nhaarman.mockitokotlin2.mock
-import com.nhaarman.mockitokotlin2.whenever
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
+import org.robolectric.Robolectric
+import org.robolectric.annotation.Config
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(ComposeUiRobolectricTestRunner::class)
+@Config(
+    manifest = Config.NONE,
+    minSdk = 26)
 class AndroidPopulateViewStructureTest {
+    private val PACKAGE_NAME = "androidx.ui.platform.test"
     private val autofillTree = AutofillTree()
     private lateinit var androidAutofill: AndroidAutofill
 
     @Before
     fun setup() {
-        val autofillManager: AutofillManager = mock()
-
-        val context: Context = mock()
-        whenever(context.getSystemService(eq(AutofillManager::class.java)))
-            .thenReturn(autofillManager)
-        whenever(context.packageName).thenReturn("com.google.testpackage")
-
-        val view: View = mock()
-        whenever(view.context).thenReturn(context)
+        val activity = Robolectric.setupActivity(Activity::class.java)
+        val view = View(activity)
+        activity.setContentView(view)
 
         androidAutofill = AndroidAutofill(view, autofillTree)
     }
@@ -82,7 +79,7 @@
         assertThat(viewStructure).isEqualTo(FakeViewStructure().apply {
             children.add(FakeViewStructure().apply {
                 virtualId = autofillNode.id
-                packageName = "com.google.testpackage"
+                packageName = PACKAGE_NAME
                 setAutofillType(View.AUTOFILL_TYPE_TEXT)
                 setAutofillHints(arrayOf(View.AUTOFILL_HINT_NAME))
                 setDimens(0, 0, 0, 0, 0, 0)
@@ -115,14 +112,14 @@
         assertThat(viewStructure).isEqualTo(FakeViewStructure().apply {
             children.add(FakeViewStructure().apply {
                 virtualId = nameAutofillNode.id
-                packageName = "com.google.testpackage"
+                packageName = PACKAGE_NAME
                 setAutofillType(View.AUTOFILL_TYPE_TEXT)
                 setAutofillHints(arrayOf(View.AUTOFILL_HINT_NAME))
                 setDimens(0, 0, 0, 0, 0, 0)
             })
             children.add(FakeViewStructure().apply {
                 virtualId = emailAutofillNode.id
-                packageName = "com.google.testpackage"
+                packageName = PACKAGE_NAME
                 setAutofillType(View.AUTOFILL_TYPE_TEXT)
                 setAutofillHints(arrayOf(View.AUTOFILL_HINT_EMAIL_ADDRESS))
                 setDimens(0, 0, 0, 0, 0, 0)