Refactor IMEAndLanguageSettings to use PreferenceController

Bug: 32642706
Bug: 32637613
Bug: 32643833
Test: RunSettingsRoboTests

This change is necessary to test preference controlling logic, as well
as making preferences reusable in other Preference pages in the new
information architecture.

Change-Id: I9e2fd2f6800579f005a5c303ed03ae06477006a6
This commit is contained in:
Fan Zhang
2016-11-03 13:29:06 -07:00
parent e185c5cc19
commit 22d42d52cf
14 changed files with 954 additions and 267 deletions

View File

@@ -22,6 +22,7 @@ import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.Before;
@@ -30,7 +31,6 @@ import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@@ -41,7 +41,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SwipeToNotificationPreferenceControllerTest {

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2016 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.inputmethod;
import android.content.Context;
import android.hardware.input.InputManager;
import android.view.InputDevice;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class GameControllerPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private InputManager mInputManager;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private InputDevice mInputDevice;
private GameControllerPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.INPUT_SERVICE)).thenReturn(mInputManager);
mController = new GameControllerPreferenceController(mContext);
}
@Test
public void testLifecycle_shouldRegisterInputManager() {
mController.onResume();
// register is called, but unregister should not be called.
verify(mInputManager).registerInputDeviceListener(mController, null);
verify(mInputManager, never()).unregisterInputDeviceListener(mController);
mController.onPause();
// register is not called any more times, but unregister should be called once.
verify(mInputManager).registerInputDeviceListener(mController, null);
verify(mInputManager).unregisterInputDeviceListener(mController);
}
@Test
public void testIsAvailable_hasDeviceWithVibrator_shouldReturnTrue() {
when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{1});
when(mInputManager.getInputDevice(1)).thenReturn(mInputDevice);
when(mInputDevice.isVirtual()).thenReturn(false);
when(mInputDevice.getVibrator().hasVibrator()).thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void testIsAvailable_hasNoVibratingDevice_shouldReturnFalse() {
when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{1});
when(mInputManager.getInputDevice(1)).thenReturn(mInputDevice);
when(mInputDevice.isVirtual()).thenReturn(false);
when(mInputDevice.getVibrator().hasVibrator()).thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testIsAvailable_hasNoPhysicalDevice_shouldReturnFalse() {
when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{1});
when(mInputManager.getInputDevice(1)).thenReturn(mInputDevice);
when(mInputDevice.isVirtual()).thenReturn(true);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testIsAvailable_hasNoDevice_shouldReturnFalse() {
when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{});
assertThat(mController.isAvailable()).isFalse();
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2016 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.inputmethod;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.TextServicesManager;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SpellCheckerPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private TextServicesManager mTextServicesManager;
private Context mAppContext;
private Preference mPreference;
private SpellCheckerPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mAppContext = ShadowApplication.getInstance().getApplicationContext();
when(mContext.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE))
.thenReturn(mTextServicesManager);
mPreference = new Preference(mAppContext);
mController = new SpellCheckerPreferenceController(mContext);
}
@Test
public void updateState_NoSpellerChecker_shouldSetSummaryToDefault() {
when(mTextServicesManager.isSpellCheckerEnabled()).thenReturn(true);
when(mTextServicesManager.getCurrentSpellChecker()).thenReturn(null);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mAppContext.getString(R.string.spell_checker_not_selected));
}
@Test
public void updateState_spellerCheckerDisabled_shouldSetSummaryToDisabledText() {
when(mTextServicesManager.isSpellCheckerEnabled()).thenReturn(false);
mController.updateState(mPreference);
assertThat(mPreference.getSummary())
.isEqualTo(mAppContext.getString(R.string.switch_off_text));
}
@Test
public void updateState_hasSpellerChecker_shouldSetSummaryToAppName() {
final String spellCheckerAppLabel = "test";
final SpellCheckerInfo sci = mock(SpellCheckerInfo.class);
when(mTextServicesManager.isSpellCheckerEnabled()).thenReturn(true);
when(mTextServicesManager.getCurrentSpellChecker()).thenReturn(sci);
when(sci.loadLabel(mContext.getPackageManager())).thenReturn(spellCheckerAppLabel);
mController.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(spellCheckerAppLabel);
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2016 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.language;
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class PhoneLanguagePreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private Preference mPreference;
private FakeFeatureFactory mFeatureFactory;
private PhoneLanguagePreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
mController = new PhoneLanguagePreferenceController(mContext);
}
@Test
public void testIsAvailable_hasMultipleLocales_shouldReturnTrue() {
when(mContext.getAssets().getLocales()).thenReturn(new String[]{"en", "de"});
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void testIsAvailable_hasSingleLocales_shouldReturnFalse() {
when(mContext.getAssets().getLocales()).thenReturn(new String[]{"en"});
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testUpdateState_shouldUpdateSummary() {
final String testSummary = "test";
when(mFeatureFactory.localeFeatureProvider.getLocaleNames()).thenReturn(testSummary);
mController.updateState(mPreference);
verify(mPreference).setSummary(testSummary);
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2016 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.language;
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TtsEngines;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
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.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class TtsPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private TtsEngines mTtsEngines;
@Mock
private PreferenceScreen mScreen;
private TtsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mController = new TtsPreferenceController(mContext, mTtsEngines);
}
@Test
public void testIsAvailable_ttsEngineEmpty_shouldReturnFalse() {
// Not available when there is no engine.
when(mTtsEngines.getEngines()).thenReturn(new ArrayList<>());
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testIsAvailable_ttsEngineInstalled_shouldReturnTrue() {
final List<TextToSpeech.EngineInfo> infolist = new ArrayList<>();
infolist.add(mock(TextToSpeech.EngineInfo.class));
when(mTtsEngines.getEngines()).thenReturn(infolist);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void displayPreference_notAvailable_shouldRemoveCategory() {
when(mScreen.findPreference(anyString())).thenReturn(mock(Preference.class));
mController.displayPreference(mScreen);
// Remove both category and preference.
verify(mScreen, times(2)).removePreference(any(Preference.class));
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (C) 2016 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.language;
import android.content.Context;
import android.speech.tts.TtsEngines;
import android.support.v7.preference.Preference;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.UserDictionarySettings;
import com.android.settings.inputmethod.UserDictionaryList;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import java.util.TreeSet;
import static com.google.common.truth.Truth.assertThat;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class UserDictionaryPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private TtsEngines mTtsEngines;
private Preference mPreference;
private TestController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest(mContext);
mController = new TestController(mContext);
mPreference = new Preference(ShadowApplication.getInstance().getApplicationContext());
}
@Test
public void testIsAvailable_noLocale_shouldReturnFalse() {
mController.mLocales = null;
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testIsAvailable_hasLocale_shouldReturnTrue() {
mController.mLocales.add("en");
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void updateState_noLocale_setUserDictionarySettingsAsFragment() {
mController.updateState(mPreference);
assertThat(mPreference.getFragment())
.isEqualTo(UserDictionarySettings.class.getCanonicalName());
}
@Test
public void updateState_singleLocale_setUserDictionarySettingsAsFragment_setLocaleInExtra() {
mController.mLocales.add("en");
mController.updateState(mPreference);
assertThat(mPreference.getFragment())
.isEqualTo(UserDictionarySettings.class.getCanonicalName());
assertThat(mPreference.getExtras().getString("locale"))
.isEqualTo("en");
}
@Test
public void updateState_multiLocale_setUserDictionaryListAsFragment() {
mController.mLocales.add("en");
mController.mLocales.add("de");
mController.updateState(mPreference);
assertThat(mPreference.getFragment())
.isEqualTo(UserDictionaryList.class.getCanonicalName());
}
/**
* Fake Controller that overrides getDictionaryLocales to make testing the rest of stuff easier.
*/
private class TestController extends UserDictionaryPreferenceController {
private TreeSet<String> mLocales = new TreeSet<>();
@Override
protected TreeSet<String> getDictionaryLocales() {
return mLocales;
}
public TestController(Context context) {
super(context);
}
}
}