Sync search result loaders
The loaders should be syncronized so the results can be properly ranked without sudden insertions. This means InstalledAppsLoader needs to finish faster, which is accomplished by delaying icon loading to bind time rather than as the apps are queried. Bug: 34772522 Test: make RunSettingsRoboTests Change-Id: I7f5244c574d37c6cfd8bbd0d3d40488f38211be3
This commit is contained in:
@@ -79,124 +79,124 @@ public class DatabaseResultLoaderTest {
|
||||
|
||||
@Test
|
||||
public void testMatchTitle() {
|
||||
loader = new DatabaseResultLoader(mContext, "title");
|
||||
loader = new DatabaseResultLoader(mContext, "title", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(2);
|
||||
verify(mSiteMapManager, times(2)).buildBreadCrumb(eq(mContext), anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchSummary() {
|
||||
loader = new DatabaseResultLoader(mContext, "summary");
|
||||
loader = new DatabaseResultLoader(mContext, "summary", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchKeywords() {
|
||||
loader = new DatabaseResultLoader(mContext, "keywords");
|
||||
loader = new DatabaseResultLoader(mContext, "keywords", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchEntries() {
|
||||
loader = new DatabaseResultLoader(mContext, "entries");
|
||||
loader = new DatabaseResultLoader(mContext, "entries", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseWord_MatchesNonPrefix() {
|
||||
insertSpecialCase("Data usage");
|
||||
loader = new DatabaseResultLoader(mContext, "usage");
|
||||
loader = new DatabaseResultLoader(mContext, "usage", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseSpace_Matches() {
|
||||
insertSpecialCase("space");
|
||||
loader = new DatabaseResultLoader(mContext, " space ");
|
||||
loader = new DatabaseResultLoader(mContext, " space ", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseDash_MatchesWordNoDash() {
|
||||
insertSpecialCase("wi-fi calling");
|
||||
loader = new DatabaseResultLoader(mContext, "wifi");
|
||||
loader = new DatabaseResultLoader(mContext, "wifi", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseDash_MatchesWordWithDash() {
|
||||
insertSpecialCase("priorités seulment");
|
||||
loader = new DatabaseResultLoader(mContext, "priorités");
|
||||
loader = new DatabaseResultLoader(mContext, "priorités", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseDash_MatchesWordWithoutDash() {
|
||||
insertSpecialCase("priorités seulment");
|
||||
loader = new DatabaseResultLoader(mContext, "priorites");
|
||||
loader = new DatabaseResultLoader(mContext, "priorites", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseDash_MatchesEntireQueryWithoutDash() {
|
||||
insertSpecialCase("wi-fi calling");
|
||||
loader = new DatabaseResultLoader(mContext, "wifi calling");
|
||||
loader = new DatabaseResultLoader(mContext, "wifi calling", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCasePrefix_MatchesPrefixOfEntry() {
|
||||
insertSpecialCase("Photos");
|
||||
loader = new DatabaseResultLoader(mContext, "pho");
|
||||
loader = new DatabaseResultLoader(mContext, "pho", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCasePrefix_DoesNotMatchNonPrefixSubstring() {
|
||||
insertSpecialCase("Photos");
|
||||
loader = new DatabaseResultLoader(mContext, "hot");
|
||||
loader = new DatabaseResultLoader(mContext, "hot", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseMultiWordPrefix_MatchesPrefixOfEntry() {
|
||||
insertSpecialCase("Apps Notifications");
|
||||
loader = new DatabaseResultLoader(mContext, "Apps");
|
||||
loader = new DatabaseResultLoader(mContext, "Apps", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseMultiWordPrefix_MatchesSecondWordPrefixOfEntry() {
|
||||
insertSpecialCase("Apps Notifications");
|
||||
loader = new DatabaseResultLoader(mContext, "Not");
|
||||
loader = new DatabaseResultLoader(mContext, "Not", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfFirstEntry() {
|
||||
insertSpecialCase("Apps Notifications");
|
||||
loader = new DatabaseResultLoader(mContext, "pp");
|
||||
loader = new DatabaseResultLoader(mContext, "pp", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfSecondEntry() {
|
||||
insertSpecialCase("Apps Notifications");
|
||||
loader = new DatabaseResultLoader(mContext, "tion");
|
||||
loader = new DatabaseResultLoader(mContext, "tion", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfEntry() {
|
||||
insertSpecialCase("Apps & Notifications");
|
||||
loader = new DatabaseResultLoader(mContext, "App");
|
||||
loader = new DatabaseResultLoader(mContext, "App", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfSecondEntry() {
|
||||
insertSpecialCase("Apps & Notifications");
|
||||
loader = new DatabaseResultLoader(mContext, "No");
|
||||
loader = new DatabaseResultLoader(mContext, "No", mSiteMapManager);
|
||||
assertThat(loader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,7 @@ package com.android.settings.search;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
@@ -26,11 +27,14 @@ import android.widget.FrameLayout;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.search2.AppSearchResult;
|
||||
import com.android.settings.search2.DatabaseResultLoader;
|
||||
import com.android.settings.search2.InlineSwitchViewHolder;
|
||||
import com.android.settings.search2.InstalledAppResultLoader;
|
||||
import com.android.settings.search2.IntentPayload;
|
||||
import com.android.settings.search2.IntentSearchViewHolder;
|
||||
import com.android.settings.search2.ResultPayload;
|
||||
import com.android.settings.search2.SearchActivity;
|
||||
import com.android.settings.search2.SearchFragment;
|
||||
import com.android.settings.search2.SearchResult;
|
||||
import com.android.settings.search2.SearchResult.Builder;
|
||||
@@ -46,11 +50,13 @@ import org.robolectric.Robolectric;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.shadows.ShadowViewGroup;
|
||||
import org.robolectric.util.ActivityController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
@@ -79,17 +85,8 @@ public class SearchAdapterTest {
|
||||
@Test
|
||||
public void testSingleSourceMerge_ExactCopyReturned() {
|
||||
ArrayList<SearchResult> intentResults = getIntentSampleResults();
|
||||
mAdapter.mergeResults(intentResults, mLoaderClassName);
|
||||
|
||||
List<SearchResult> updatedResults = mAdapter.getSearchResults();
|
||||
assertThat(updatedResults).containsAllIn(intentResults);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateSourceMerge_ExactCopyReturned() {
|
||||
ArrayList<SearchResult> intentResults = getIntentSampleResults();
|
||||
mAdapter.mergeResults(intentResults, mLoaderClassName);
|
||||
mAdapter.mergeResults(intentResults, mLoaderClassName);
|
||||
mAdapter.addResultsToMap(intentResults, mLoaderClassName);
|
||||
mAdapter.mergeResults();
|
||||
|
||||
List<SearchResult> updatedResults = mAdapter.getSearchResults();
|
||||
assertThat(updatedResults).containsAllIn(intentResults);
|
||||
@@ -111,6 +108,65 @@ public class SearchAdapterTest {
|
||||
assertThat(view).isInstanceOf(InlineSwitchViewHolder.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEndToEndSearch_ProperResultsMerged() {
|
||||
mAdapter.addResultsToMap(getDummyAppResults(),
|
||||
InstalledAppResultLoader.class.getName());
|
||||
mAdapter.addResultsToMap(getDummyDbResults(),
|
||||
DatabaseResultLoader.class.getName());
|
||||
mAdapter.mergeResults();
|
||||
|
||||
List<SearchResult> results = mAdapter.getSearchResults();
|
||||
assertThat(results.get(0).title).isEqualTo("alpha");
|
||||
assertThat(results.get(1).title).isEqualTo("appAlpha");
|
||||
assertThat(results.get(2).title).isEqualTo("appBravo");
|
||||
assertThat(results.get(3).title).isEqualTo("bravo");
|
||||
assertThat(results.get(4).title).isEqualTo("appCharlie");
|
||||
assertThat(results.get(5).title).isEqualTo("Charlie");
|
||||
}
|
||||
|
||||
private List<SearchResult> getDummyDbResults() {
|
||||
List<SearchResult> results = new ArrayList<>();
|
||||
IntentPayload payload = new IntentPayload(new Intent());
|
||||
SearchResult.Builder builder = new SearchResult.Builder();
|
||||
builder.addPayload(payload);
|
||||
|
||||
builder.addTitle("alpha")
|
||||
.addRank(1);
|
||||
results.add(builder.build());
|
||||
|
||||
builder.addTitle("bravo")
|
||||
.addRank(3);
|
||||
results.add(builder.build());
|
||||
|
||||
builder.addTitle("Charlie")
|
||||
.addRank(6);
|
||||
results.add(builder.build());
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<AppSearchResult> getDummyAppResults() {
|
||||
List<AppSearchResult> results = new ArrayList<>();
|
||||
IntentPayload payload = new IntentPayload(new Intent());
|
||||
AppSearchResult.Builder builder = new AppSearchResult.Builder();
|
||||
builder.addPayload(payload);
|
||||
|
||||
builder.addTitle("appAlpha")
|
||||
.addRank(1);
|
||||
results.add(builder.build());
|
||||
|
||||
builder.addTitle("appBravo")
|
||||
.addRank(2);
|
||||
results.add(builder.build());
|
||||
|
||||
builder.addTitle("appCharlie")
|
||||
.addRank(4);
|
||||
results.add(builder.build());
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private ArrayList<SearchResult> getIntentSampleResults() {
|
||||
ArrayList<SearchResult> sampleResults = new ArrayList<>();
|
||||
ArrayList<String> breadcrumbs = new ArrayList<>();
|
||||
|
@@ -94,6 +94,8 @@ public class InstalledAppResultLoaderTest {
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, "app4", 0 /* flags */,
|
||||
0 /* targetSdkVersion */),
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, "app", 0 /* flags */,
|
||||
0 /* targetSdkVersion */),
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, "appBuffer", 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
}
|
||||
|
||||
@@ -101,7 +103,8 @@ public class InstalledAppResultLoaderTest {
|
||||
public void query_noMatchingQuery_shouldReturnEmptyResult() {
|
||||
final String query = "abc";
|
||||
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground()).isEmpty();
|
||||
}
|
||||
@@ -110,12 +113,13 @@ public class InstalledAppResultLoaderTest {
|
||||
public void query_matchingQuery_shouldReturnNonSystemApps() {
|
||||
final String query = "app";
|
||||
|
||||
mLoader = spy(new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query));
|
||||
mLoader = spy(new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager));
|
||||
when(mLoader.getContext()).thenReturn(mContext);
|
||||
when(mSiteMapManager.buildBreadCrumb(eq(mContext), anyString(), anyString()))
|
||||
.thenReturn(Arrays.asList(new String[]{"123"}));
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(2);
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(3);
|
||||
verify(mSiteMapManager)
|
||||
.buildBreadCrumb(eq(mContext), anyString(), anyString());
|
||||
}
|
||||
@@ -128,7 +132,8 @@ public class InstalledAppResultLoaderTest {
|
||||
0 /* targetSdkVersion */)));
|
||||
final String query = "app";
|
||||
|
||||
mLoader = spy(new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query));
|
||||
mLoader = spy(new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager));
|
||||
when(mLoader.getContext()).thenReturn(mContext);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
@@ -150,7 +155,8 @@ public class InstalledAppResultLoaderTest {
|
||||
|
||||
final String query = "app";
|
||||
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -167,7 +173,8 @@ public class InstalledAppResultLoaderTest {
|
||||
|
||||
final String query = "app";
|
||||
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground()).isEmpty();
|
||||
verify(mSiteMapManager, never())
|
||||
@@ -178,15 +185,15 @@ public class InstalledAppResultLoaderTest {
|
||||
public void query_matchingQuery_shouldRankBasedOnSimilarity() {
|
||||
final String query = "app";
|
||||
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
final List<SearchResult> results = mLoader.loadInBackground();
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
final List<? extends SearchResult> results = mLoader.loadInBackground();
|
||||
|
||||
// List is sorted by rank
|
||||
assertThat(results.get(0).rank).isLessThan(results.get(1).rank);
|
||||
// perfect match first
|
||||
assertThat(results.get(0).title).isEqualTo(query);
|
||||
// Then partial match
|
||||
assertThat(results.get(1).title).isNotEqualTo(query);
|
||||
assertThat(results.get(0).rank).isAtMost(results.get(1).rank);
|
||||
assertThat(results.get(0).title).isEqualTo("app4");
|
||||
assertThat(results.get(1).title).isEqualTo("app");
|
||||
assertThat(results.get(2).title).isEqualTo("appBuffer");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -197,7 +204,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -210,7 +218,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(0);
|
||||
}
|
||||
@@ -223,7 +232,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -236,7 +246,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -249,7 +260,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -262,7 +274,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -275,7 +288,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -288,7 +302,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -301,7 +316,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(1);
|
||||
}
|
||||
@@ -314,7 +330,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(0);
|
||||
}
|
||||
@@ -327,7 +344,8 @@ public class InstalledAppResultLoaderTest {
|
||||
.thenReturn(Arrays.asList(
|
||||
ApplicationTestUtils.buildInfo(0 /* uid */, packageName, 0 /* flags */,
|
||||
0 /* targetSdkVersion */)));
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query);
|
||||
mLoader = new InstalledAppResultLoader(mContext, mPackageManagerWrapper, query,
|
||||
mSiteMapManager);
|
||||
|
||||
assertThat(mLoader.loadInBackground().size()).isEqualTo(0);
|
||||
}
|
||||
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.search2;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mock loader to subvert the requirements of returning data while also driving the Loader
|
||||
* lifecycle.
|
||||
*/
|
||||
class MockAppLoader extends InstalledAppResultLoader {
|
||||
|
||||
public MockAppLoader(Context context) {
|
||||
super(context, null, "", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends SearchResult> loadInBackground() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDiscardResult(List<? extends SearchResult> result) {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.search2;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mock loader to subvert the requirements of returning data while also driving the Loader
|
||||
* lifecycle.
|
||||
*/
|
||||
class MockDBLoader extends DatabaseResultLoader {
|
||||
|
||||
public MockDBLoader(Context context) {
|
||||
super(context, "test", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends SearchResult> loadInBackground() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDiscardResult(List<? extends SearchResult> result) {
|
||||
|
||||
}
|
||||
}
|
@@ -60,7 +60,7 @@ public class SavedQueryLoaderTest {
|
||||
|
||||
@Test
|
||||
public void loadInBackground_shouldReturnSavedQueries() {
|
||||
final List<SearchResult> results = mLoader.loadInBackground();
|
||||
final List<? extends SearchResult> results = mLoader.loadInBackground();
|
||||
assertThat(results.size()).isEqualTo(SavedQueryLoader.MAX_PROPOSED_SUGGESTIONS);
|
||||
for (SearchResult result : results) {
|
||||
assertThat(result.viewType).isEqualTo(ResultPayload.PayloadType.SAVED_QUERY);
|
||||
|
@@ -59,7 +59,7 @@ public class SavedQueryRecorderTest {
|
||||
mRecorder.loadInBackground();
|
||||
|
||||
final SavedQueryLoader loader = new SavedQueryLoader(mContext);
|
||||
List<SearchResult> results = loader.loadInBackground();
|
||||
List<? extends SearchResult> results = loader.loadInBackground();
|
||||
|
||||
assertThat(results.size()).isEqualTo(1);
|
||||
assertThat(results.get(0).title).isEqualTo(query);
|
||||
|
@@ -20,12 +20,16 @@ import android.content.Context;
|
||||
import android.content.Loader;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.os.UserManager;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.dashboard.SiteMapManager;
|
||||
import com.android.settings.testutils.DatabaseTestUtils;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -33,16 +37,20 @@ import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ActivityController;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -57,6 +65,7 @@ public class SearchFragmentTest {
|
||||
private DatabaseResultLoader mDatabaseResultLoader;
|
||||
@Mock
|
||||
private InstalledAppResultLoader mInstalledAppResultLoader;
|
||||
|
||||
@Mock
|
||||
private SavedQueryLoader mSavedQueryLoader;
|
||||
|
||||
@@ -65,8 +74,13 @@ public class SearchFragmentTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
FakeFeatureFactory.setupForTest(mContext);
|
||||
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void screenRotate_shouldPersistQuery() {
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getDatabaseSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mDatabaseResultLoader);
|
||||
@@ -75,10 +89,7 @@ public class SearchFragmentTest {
|
||||
.thenReturn(mInstalledAppResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
|
||||
.thenReturn(mSavedQueryLoader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void screenRotate_shouldPersistQuery() {
|
||||
final Bundle bundle = new Bundle();
|
||||
final String testQuery = "test";
|
||||
ActivityController<SearchActivity> activityController =
|
||||
@@ -102,6 +113,15 @@ public class SearchFragmentTest {
|
||||
|
||||
@Test
|
||||
public void screenRotateEmptyString_ShouldNotCrash() {
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getDatabaseSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mDatabaseResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getInstalledAppSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mInstalledAppResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
|
||||
.thenReturn(mSavedQueryLoader);
|
||||
|
||||
final Bundle bundle = new Bundle();
|
||||
ActivityController<SearchActivity> activityController =
|
||||
Robolectric.buildActivity(SearchActivity.class);
|
||||
@@ -124,6 +144,15 @@ public class SearchFragmentTest {
|
||||
|
||||
@Test
|
||||
public void queryTextChange_shouldTriggerLoader() {
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getDatabaseSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mDatabaseResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getInstalledAppSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mInstalledAppResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
|
||||
.thenReturn(mSavedQueryLoader);
|
||||
|
||||
final String testQuery = "test";
|
||||
ActivityController<SearchActivity> activityController =
|
||||
Robolectric.buildActivity(SearchActivity.class);
|
||||
@@ -148,6 +177,15 @@ public class SearchFragmentTest {
|
||||
|
||||
@Test
|
||||
public void queryTextChangeToEmpty_shouldTriggerSavedQueryLoader() {
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getDatabaseSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mDatabaseResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getInstalledAppSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mInstalledAppResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
|
||||
.thenReturn(mSavedQueryLoader);
|
||||
|
||||
ActivityController<SearchActivity> activityController =
|
||||
Robolectric.buildActivity(SearchActivity.class);
|
||||
activityController.setup();
|
||||
@@ -169,6 +207,15 @@ public class SearchFragmentTest {
|
||||
|
||||
@Test
|
||||
public void updateIndex_TriggerOnCreate() {
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getDatabaseSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mDatabaseResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getInstalledAppSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(mInstalledAppResultLoader);
|
||||
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
|
||||
.thenReturn(mSavedQueryLoader);
|
||||
|
||||
ActivityController<SearchActivity> activityController =
|
||||
Robolectric.buildActivity(SearchActivity.class);
|
||||
activityController.setup();
|
||||
@@ -178,4 +225,28 @@ public class SearchFragmentTest {
|
||||
fragment.onAttach(null);
|
||||
verify(mFeatureFactory.searchFeatureProvider).updateIndex(any(Context.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void syncLoaders_MergeWhenAllLoadersDone() {
|
||||
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getDatabaseSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(new MockDBLoader(RuntimeEnvironment.application));
|
||||
when(mFeatureFactory.searchFeatureProvider
|
||||
.getInstalledAppSearchLoader(any(Context.class), anyString()))
|
||||
.thenReturn(new MockAppLoader(RuntimeEnvironment.application));
|
||||
|
||||
ActivityController<SearchActivity> activityController =
|
||||
Robolectric.buildActivity(SearchActivity.class);
|
||||
activityController.setup();
|
||||
SearchFragment fragment = (SearchFragment) spy(activityController.get().getFragmentManager()
|
||||
.findFragmentById(R.id.main_content));
|
||||
|
||||
fragment.onQueryTextChange("non-empty");
|
||||
|
||||
Robolectric.flushForegroundThreadScheduler();
|
||||
|
||||
verify(fragment, times(2)).onLoadFinished(any(Loader.class), any(List.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user