blob: 1ec209486c18a6d15b0368c24f35c06ae210a2a4 [file] [log] [blame]
Winson9947f1e2019-08-16 10:20:39 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package android.content.res.loader.test
18
19import android.content.res.Resources
20import android.content.res.XmlResourceParser
21import android.content.res.loader.ResourceLoader
22import android.content.res.loader.ResourcesProvider
23import com.google.common.truth.Truth.assertThat
24import org.hamcrest.CoreMatchers.not
25import org.junit.Assume.assumeThat
26import org.junit.Test
27import org.junit.runner.RunWith
28import org.junit.runners.Parameterized
29import org.mockito.ArgumentMatchers.anyString
30import org.mockito.Mockito.`when`
31import org.mockito.Mockito.any
32import org.mockito.Mockito.anyInt
33import org.mockito.Mockito.mock
34import org.mockito.Mockito.never
35import org.mockito.Mockito.verify
36
37@RunWith(Parameterized::class)
38class ResourceLoaderLayoutTest : ResourceLoaderTestBase() {
39
40 companion object {
41
42 @JvmStatic
43 @Parameterized.Parameters(name = "{0}")
44 fun data() = arrayOf(DataType.APK, DataType.ARSC)
45 }
46
47 @field:Parameterized.Parameter(0)
48 override lateinit var dataType: DataType
49
50 @Test
51 fun singleLoader() {
52 val original = getLayout(android.R.layout.activity_list_item)
53 val mockXml = mock(XmlResourceParser::class.java)
54 val loader = "layoutWithoutFile".openLoader()
55 `when`(loader.first.loadXmlResourceParser(any(), anyInt()))
56 .thenReturn(mockXml)
57
58 addLoader(loader)
59
60 val layout = getLayout(android.R.layout.activity_list_item)
61 loader.verifyLoadLayoutCalled()
62
63 assertThat(layout).isNotEqualTo(original)
64 assertThat(layout).isSameAs(mockXml)
65 }
66
67 @Test
68 fun multipleLoaders() {
69 val original = getLayout(android.R.layout.activity_list_item)
70 val loaderOne = "layoutWithoutFile".openLoader()
71 val loaderTwo = "layoutWithoutFile".openLoader()
72
73 val mockXml = mock(XmlResourceParser::class.java)
74 `when`(loaderTwo.first.loadXmlResourceParser(any(), anyInt()))
75 .thenReturn(mockXml)
76
77 addLoader(loaderOne, loaderTwo)
78
79 val layout = getLayout(android.R.layout.activity_list_item)
80 loaderOne.verifyLoadLayoutNotCalled()
81 loaderTwo.verifyLoadLayoutCalled()
82
83 assertThat(layout).isNotEqualTo(original)
84 assertThat(layout).isSameAs(mockXml)
85 }
86
87 @Test(expected = Resources.NotFoundException::class)
88 fun multipleLoadersNoReturnWithoutFile() {
89 val loaderOne = "layoutWithoutFile".openLoader()
90 val loaderTwo = "layoutWithoutFile".openLoader()
91
92 addLoader(loaderOne, loaderTwo)
93
94 try {
95 getLayout(android.R.layout.activity_list_item)
96 } finally {
97 // We expect the call to fail because at least one loader must resolve the overridden
98 // layout, but we should still verify that both loaders were called before allowing
99 // the exception to propagate.
100 loaderOne.verifyLoadLayoutNotCalled()
101 loaderTwo.verifyLoadLayoutCalled()
102 }
103 }
104
105 @Test
106 fun multipleLoadersReturnWithFile() {
107 // Can't return a file if an ARSC
108 assumeThat(dataType, not(DataType.ARSC))
109
110 val loaderOne = "layoutWithFile".openLoader()
111 val loaderTwo = "layoutWithFile".openLoader()
112
113 addLoader(loaderOne, loaderTwo)
114
115 val xml = getLayout(android.R.layout.activity_list_item)
116 loaderOne.verifyLoadLayoutNotCalled()
117 loaderTwo.verifyLoadLayoutCalled()
118
119 assertThat(xml).isNotNull()
120 }
121
122 @Test
123 fun unhandledResourceIgnoresLoaders() {
124 val loader = "layoutWithoutFile".openLoader()
125 val mockXml = mock(XmlResourceParser::class.java)
126 `when`(loader.first.loadXmlResourceParser(any(), anyInt()))
127 .thenReturn(mockXml)
128 addLoader(loader)
129
130 getLayout(android.R.layout.preference_category)
131
132 verify(loader.first, never())
133 .loadXmlResourceParser(anyString(), anyInt())
134
135 getLayout(android.R.layout.activity_list_item)
136
137 loader.verifyLoadLayoutCalled()
138 }
139
140 private fun Pair<ResourceLoader, ResourcesProvider>.verifyLoadLayoutCalled() {
141 verify(first).loadXmlResourceParser(
142 "res/layout/activity_list_item.xml",
143 android.R.layout.activity_list_item
144 )
145 }
146
147 private fun Pair<ResourceLoader, ResourcesProvider>.verifyLoadLayoutNotCalled() {
148 verify(first, never()).loadXmlResourceParser(
149 anyString(),
150 anyInt()
151 )
152 }
153}