| // Copyright 2010-2015, Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| package org.mozc.android.inputmethod.japanese; |
| |
| import static org.easymock.EasyMock.expect; |
| import static org.easymock.EasyMock.expectLastCall; |
| import static org.easymock.EasyMock.isA; |
| |
| import org.mozc.android.inputmethod.japanese.FeedbackManager.FeedbackEvent; |
| import org.mozc.android.inputmethod.japanese.emoji.EmojiProviderType; |
| import org.mozc.android.inputmethod.japanese.model.SymbolCandidateStorage; |
| import org.mozc.android.inputmethod.japanese.model.SymbolCandidateStorage.SymbolHistoryStorage; |
| import org.mozc.android.inputmethod.japanese.model.SymbolMajorCategory; |
| import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateWord; |
| import org.mozc.android.inputmethod.japanese.testing.InstrumentationTestCaseWithMock; |
| import org.mozc.android.inputmethod.japanese.testing.Parameter; |
| import com.google.common.base.Optional; |
| |
| import android.app.AlertDialog; |
| import android.content.Context; |
| import android.test.suitebuilder.annotation.SmallTest; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| |
| import java.util.Collections; |
| |
| /** |
| */ |
| public class SymbolInputViewTest extends InstrumentationTestCaseWithMock { |
| // TODO(hidehiko): Add tests for switchToPreviousCandidateView for b/5772179, as it's much |
| // difficult to test the method, and now we don't have the test for it. |
| // Refactoring, which I'm working on, would make it possible, |
| // but fixing the bug is prioritiezed. |
| |
| @SmallTest |
| public void testMajorCategoryButtonClickListener() { |
| SymbolInputView symbolInputView = createViewMock(SymbolInputView.class); |
| |
| for (SymbolMajorCategory majorCategory : SymbolMajorCategory.values()) { |
| resetAll(); |
| symbolInputView.setMajorCategory(majorCategory); |
| replayAll(); |
| |
| symbolInputView.new MajorCategoryButtonClickListener(majorCategory).onClick(null); |
| |
| verifyAll(); |
| } |
| } |
| |
| @SmallTest |
| public void testMajorCategoryButtonClickListenerForNoneProvider() { |
| Context context = getInstrumentation().getTargetContext(); |
| SymbolInputView symbolInputView = createViewMock(SymbolInputView.class); |
| |
| symbolInputView.emojiEnabled = true; |
| symbolInputView.emojiProviderType = EmojiProviderType.NONE; |
| // Set sharedPreferences null to emulate detection failure. |
| symbolInputView.sharedPreferences = null; |
| |
| AlertDialog dialog = createDialogMock(AlertDialog.class); |
| symbolInputView.emojiProviderDialog = Optional.of(dialog); |
| |
| symbolInputView.maybeInitializeEmojiProviderDialog(context); |
| expect(symbolInputView.getWindowToken()).andReturn(null); |
| // The dialog should be shown. |
| dialog.show(); |
| replayAll(); |
| |
| symbolInputView.new MajorCategoryButtonClickListener(SymbolMajorCategory.EMOJI).onClick(null); |
| |
| verifyAll(); |
| assertSame(EmojiProviderType.NONE, symbolInputView.emojiProviderType); |
| } |
| |
| private void checkConsistency(SymbolInputView view) { |
| SymbolMajorCategory major = view.currentMajorCategory; |
| for (SymbolMajorCategory category : SymbolMajorCategory.values()) { |
| // Check if only the selected major category's button is "selected" and "enabled". |
| View majorCategoryButton = view.getMajorCategoryButton(category); |
| assertEquals(category == major, majorCategoryButton.isSelected()); |
| assertEquals(category != major, majorCategoryButton.isEnabled()); |
| } |
| } |
| |
| @SmallTest |
| public void testSetMajorCategoryWithEmptyHistory() { |
| SymbolInputView view = new SymbolInputView(getInstrumentation().getTargetContext()); |
| SymbolHistoryStorage historyStorage = createMock(SymbolHistoryStorage.class); |
| expect(historyStorage.getAllHistory(isA(SymbolMajorCategory.class))) |
| .andStubReturn(Collections.<String>emptyList()); |
| replayAll(); |
| view.setSymbolCandidateStorage(new SymbolCandidateStorage(historyStorage)); |
| view.inflateSelf(); |
| view.reset(); |
| |
| ViewEventListener listener = createMock(ViewEventListener.class); |
| view.setEventListener( |
| listener, createNiceMock(OnClickListener.class), createNiceMock(OnClickListener.class)); |
| |
| checkConsistency(view); |
| |
| // NUMBER |
| resetAll(); |
| replayAll(); |
| |
| view.setMajorCategory(SymbolMajorCategory.NUMBER); |
| |
| verifyAll(); |
| checkConsistency(view); |
| |
| // The others |
| for (SymbolMajorCategory category : SymbolMajorCategory.values()) { |
| if (category == SymbolMajorCategory.NUMBER) { |
| continue; |
| } |
| |
| resetAll(); |
| expect(historyStorage.getAllHistory(category)).andReturn(Collections.<String>emptyList()); |
| listener.onSubmitPreedit(); |
| replayAll(); |
| |
| view.setMajorCategory(category); |
| |
| verifyAll(); |
| checkConsistency(view); |
| assertEquals(category.toString(), 1, view.getTabHost().getCurrentTab()); |
| } |
| } |
| |
| @SmallTest |
| public void testSetMajorCategoryWithHistory() { |
| SymbolInputView view = new SymbolInputView(getInstrumentation().getTargetContext()); |
| SymbolHistoryStorage historyStorage = createMock(SymbolHistoryStorage.class); |
| expect(historyStorage.getAllHistory(isA(SymbolMajorCategory.class))) |
| .andStubReturn(Collections.<String>emptyList()); |
| replayAll(); |
| view.setSymbolCandidateStorage(new SymbolCandidateStorage(historyStorage)); |
| view.inflateSelf(); |
| view.reset(); |
| |
| ViewEventListener listener = createMock(ViewEventListener.class); |
| view.setEventListener( |
| listener, createNiceMock(OnClickListener.class), createNiceMock(OnClickListener.class)); |
| checkConsistency(view); |
| |
| // NUMBER |
| resetAll(); |
| replayAll(); |
| |
| view.setMajorCategory(SymbolMajorCategory.NUMBER); |
| |
| verifyAll(); |
| checkConsistency(view); |
| |
| // The others |
| for (final SymbolMajorCategory category : SymbolMajorCategory.values()) { |
| if (category == SymbolMajorCategory.NUMBER) { |
| continue; |
| } |
| |
| resetAll(); |
| expect(historyStorage.getAllHistory(category)) |
| .andReturn(Collections.singletonList(category.name())); |
| listener.onFireFeedbackEvent(FeedbackEvent.SYMBOL_INPUTVIEW_MINOR_CATEGORY_SELECTED); |
| expectLastCall().asStub(); |
| listener.onSubmitPreedit(); |
| replayAll(); |
| |
| view.setMajorCategory(category); |
| |
| verifyAll(); |
| checkConsistency(view); |
| assertEquals(category.toString(), 0, view.getTabHost().getCurrentTab()); |
| } |
| } |
| |
| @SmallTest |
| public void testSymbolCandidateSelectListener() { |
| SymbolInputView view = new SymbolInputView(getInstrumentation().getTargetContext()); |
| SymbolHistoryStorage historyStorage = createMock(SymbolHistoryStorage.class); |
| expect(historyStorage.getAllHistory(isA(SymbolMajorCategory.class))) |
| .andStubReturn(Collections.<String>emptyList()); |
| replayAll(); |
| view.setSymbolCandidateStorage(new SymbolCandidateStorage(historyStorage)); |
| |
| view.inflateSelf(); |
| view.setMajorCategory(SymbolMajorCategory.EMOTICON); |
| |
| ViewEventListener viewEventListener = createMock(ViewEventListener.class); |
| view.setEventListener(viewEventListener, createNiceMock(OnClickListener.class), |
| createNiceMock(OnClickListener.class)); |
| |
| resetAll(); |
| viewEventListener.onSymbolCandidateSelected(SymbolMajorCategory.EMOTICON, "(^_^)", true); |
| replayAll(); |
| |
| view.new SymbolCandidateSelectListener().onCandidateSelected( |
| CandidateWord.newBuilder().setValue("(^_^)").buildPartial(), Optional.<Integer>absent()); |
| |
| verifyAll(); |
| } |
| |
| @SmallTest |
| public void testEnableEmoji() { |
| Context context = getInstrumentation().getTargetContext(); |
| SymbolInputView view = new SymbolInputView(context); |
| SymbolHistoryStorage historyStorage = createMock(SymbolHistoryStorage.class); |
| expect(historyStorage.getAllHistory(isA(SymbolMajorCategory.class))) |
| .andStubReturn(Collections.<String>emptyList()); |
| replayAll(); |
| view.setSymbolCandidateStorage(new SymbolCandidateStorage(historyStorage)); |
| view.inflateSelf(); |
| |
| class TestData extends Parameter { |
| private final boolean isUnicodeEmojiEnabled; |
| private final boolean isCarrierEmojiEnabled; |
| private final SymbolMajorCategory majorCategory; |
| private final int expectedEmojiDisabledMessageViewVisibility; |
| |
| TestData(boolean isUnicodeEmojiEnabled, boolean isCarrierEmojiEnabled, |
| SymbolMajorCategory majorCategory, int expectedEmojiDisabledMessageViewVisibility) { |
| this.isUnicodeEmojiEnabled = isUnicodeEmojiEnabled; |
| this.isCarrierEmojiEnabled = isCarrierEmojiEnabled; |
| this.majorCategory = majorCategory; |
| this.expectedEmojiDisabledMessageViewVisibility = |
| expectedEmojiDisabledMessageViewVisibility; |
| } |
| } |
| TestData[] testDataList = { |
| new TestData(true, true, SymbolMajorCategory.SYMBOL, View.GONE), |
| new TestData(true, true, SymbolMajorCategory.EMOTICON, View.GONE), |
| new TestData(true, true, SymbolMajorCategory.EMOJI, View.GONE), |
| new TestData(true, false, SymbolMajorCategory.SYMBOL, View.GONE), |
| new TestData(true, false, SymbolMajorCategory.EMOTICON, View.GONE), |
| new TestData(true, false, SymbolMajorCategory.EMOJI, View.GONE), |
| new TestData(false, true, SymbolMajorCategory.SYMBOL, View.GONE), |
| new TestData(false, true, SymbolMajorCategory.EMOTICON, View.GONE), |
| new TestData(false, true, SymbolMajorCategory.EMOJI, View.GONE), |
| new TestData(false, false, SymbolMajorCategory.SYMBOL, View.GONE), |
| new TestData(false, false, SymbolMajorCategory.EMOTICON, View.GONE), |
| new TestData(false, false, SymbolMajorCategory.EMOJI, View.VISIBLE), |
| }; |
| |
| for (TestData testData : testDataList) { |
| view.setEmojiEnabled(testData.isUnicodeEmojiEnabled, testData.isCarrierEmojiEnabled); |
| view.setMajorCategory(testData.majorCategory); |
| // Now, the emoji major-category button is always clickable. |
| assertTrue(testData.toString(), |
| view.getMajorCategoryButton(SymbolMajorCategory.EMOJI).isClickable()); |
| assertEquals(testData.toString(), |
| testData.expectedEmojiDisabledMessageViewVisibility, |
| view.getEmojiDisabledMessageView().getVisibility()); |
| } |
| } |
| } |