| // 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.anyInt; |
| import static org.easymock.EasyMock.eq; |
| import static org.easymock.EasyMock.expect; |
| import static org.easymock.EasyMock.isA; |
| import static org.easymock.EasyMock.same; |
| |
| import org.mozc.android.inputmethod.japanese.CandidateWordView.Orientation; |
| import org.mozc.android.inputmethod.japanese.CandidateWordView.OrientationTrait; |
| import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateList; |
| import org.mozc.android.inputmethod.japanese.protobuf.ProtoCandidates.CandidateWord; |
| import org.mozc.android.inputmethod.japanese.testing.InstrumentationTestCaseWithMock; |
| import org.mozc.android.inputmethod.japanese.testing.MozcLayoutUtil; |
| import org.mozc.android.inputmethod.japanese.testing.Parameter; |
| import org.mozc.android.inputmethod.japanese.testing.VisibilityProxy; |
| import org.mozc.android.inputmethod.japanese.ui.CandidateLayout; |
| import org.mozc.android.inputmethod.japanese.ui.CandidateLayout.Row; |
| import org.mozc.android.inputmethod.japanese.ui.CandidateLayout.Span; |
| import org.mozc.android.inputmethod.japanese.ui.CandidateLayouter; |
| import org.mozc.android.inputmethod.japanese.ui.SnapScroller; |
| import org.mozc.android.inputmethod.japanese.view.DummyDrawable; |
| import org.mozc.android.inputmethod.japanese.view.Skin; |
| import com.google.common.base.Optional; |
| |
| import android.annotation.SuppressLint; |
| import android.content.Context; |
| import android.graphics.drawable.Drawable; |
| import android.test.suitebuilder.annotation.SmallTest; |
| import android.view.MotionEvent; |
| import android.view.View; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| |
| /** |
| */ |
| public class CandidateWordViewTest extends InstrumentationTestCaseWithMock { |
| class StubCandidateWordView extends CandidateWordView { |
| StubCandidateWordView(Context context, OrientationTrait orientationTrait) { |
| super(context, orientationTrait); |
| } |
| |
| @Override |
| public void invalidate() { |
| // We are not willing to test rendering routine running background of event processing test. |
| // So just ignore this method's invocation. |
| } |
| |
| @Override |
| protected Drawable getViewBackgroundDrawable(Skin skin) { |
| return DummyDrawable.getInstance(); |
| } |
| } |
| |
| public static Span createNullCandidateWordSpan(int left, int right) { |
| Span span = new Span( |
| Optional.<CandidateWord>absent(), 0, 0, Collections.<String>emptyList()); |
| span.setLeft(left); |
| span.setRight(right); |
| return span; |
| } |
| |
| private static final List<Row> ROW_DATA = |
| Arrays.asList( |
| MozcLayoutUtil.createRow(10, 20, 50, |
| MozcLayoutUtil.createSpan(0, 10, 30), |
| MozcLayoutUtil.createSpan(1, 40, 60)), |
| MozcLayoutUtil.createRow(40, 20, 50, |
| MozcLayoutUtil.createSpan(0, 10, 30), |
| MozcLayoutUtil.createSpan(1, 40, 60)), |
| MozcLayoutUtil.createRow(70, 20, 50, |
| createNullCandidateWordSpan(10, 30), |
| createNullCandidateWordSpan(40, 60))); |
| |
| private static final CandidateList CANDIDATE_LIST = CandidateList.newBuilder() |
| .addCandidates(CandidateWord.newBuilder().setId(0).setValue("cand1")) |
| .addCandidates(CandidateWord.newBuilder().setId(1).setValue("cand2")) |
| .build(); |
| |
| @SmallTest |
| public void testOrientationHorizontal() { |
| View view = createViewMock(View.class); |
| OrientationTrait trait = Orientation.HORIZONTAL; |
| // getScrollPosition |
| // We cannot do enough test because we cannot control the result of |
| // View#getScrollX(). |
| assertEquals(view.getScrollX(), trait.getScrollPosition(view)); |
| |
| // scrollTo |
| view.scrollTo(100, 0); |
| replayAll(); |
| trait.scrollTo(view, 100); |
| verifyAll(); |
| |
| // getValueFromPair |
| assertEquals(100f, trait.projectVector(100f, 0f)); |
| |
| // Note that Row and Span are final class. |
| Row row = MozcLayoutUtil.createRow(100, 200, 400); |
| Span span = MozcLayoutUtil.createSpan(0, 300, 700); |
| |
| // getPosition |
| assertEquals(300f, trait.getCandidatePosition(row, span)); |
| // getLength |
| assertEquals(400f, trait.getCandidateLength(row, span)); |
| |
| // getViewLength |
| // We cannot do enough test because we cannot control the result of |
| // View#getWidth(). |
| // TODO(matsuza): Use #setLeft() method (API Level 11) |
| assertEquals(view.getWidth(), trait.getViewLength(view)); |
| } |
| |
| @SmallTest |
| public void testOrientationVertical() { |
| View view = createViewMock(View.class); |
| OrientationTrait trait = Orientation.VERTICAL; |
| |
| // getScrollPosition |
| // We cannot do enough test because we cannot control the result of |
| // View#getScrollY(). |
| assertEquals(view.getScrollY(), trait.getScrollPosition(view)); |
| |
| // scrollTo |
| view.scrollTo(0, 100); |
| replayAll(); |
| trait.scrollTo(view, 100); |
| verifyAll(); |
| |
| // getValueFromPair |
| assertEquals(100f, trait.projectVector(0f, 100f)); |
| |
| // Note that Row and Span are final class. |
| Row row = MozcLayoutUtil.createRow(100, 200, 400); |
| Span span = MozcLayoutUtil.createSpan(0, 300, 700); |
| |
| // getPosition |
| assertEquals(100f, trait.getCandidatePosition(row, span)); |
| // getLength |
| assertEquals(200f, trait.getCandidateLength(row, span)); |
| |
| // getViewLength |
| // We cannot do enough test because we cannot control the result of |
| // View#getWidth(). |
| // TODO(matsuza): Use #setBotton() method (API Level 11) |
| assertEquals(view.getHeight(), trait.getViewLength(view)); |
| } |
| |
| @SmallTest |
| public void testOnSingleTapUp() |
| throws IllegalArgumentException, SecurityException { |
| CandidateWordView candidateWordView = |
| new StubCandidateWordView(getInstrumentation().getTargetContext(), |
| CandidateWordView.Orientation.VERTICAL); |
| CandidateSelectListener candidateSelectListener = createMock(CandidateSelectListener.class); |
| candidateWordView.setCandidateSelectListener(candidateSelectListener); |
| CandidateLayout mockLayout = MozcLayoutUtil.createCandidateLayoutMock(getMockSupport()); |
| candidateWordView.calculatedLayout = mockLayout; |
| |
| // onCandidateSelected() is never be called back. |
| List<MotionEvent> events = new ArrayList<MotionEvent>(); |
| |
| try { |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, Integer.MIN_VALUE, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_UP, 0, Integer.MIN_VALUE, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, Integer.MAX_VALUE, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_UP, 0, Integer.MAX_VALUE, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, Integer.MIN_VALUE, 0, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_UP, Integer.MIN_VALUE, 0, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, Integer.MAX_VALUE, 0, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_UP, Integer.MAX_VALUE, 0, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| // TouchUp on a candidate. |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| candidateSelectListener.onCandidateSelected( |
| ROW_DATA.get(0).getSpanList().get(0).getCandidateWord().get(), Optional.<Integer>of(0)); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 10, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_UP, 10, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| // Slide within a candidate (top-left corner). |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| candidateSelectListener.onCandidateSelected( |
| ROW_DATA.get(0).getSpanList().get(0).getCandidateWord().get(), Optional.<Integer>of(0)); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 10, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_MOVE, 12, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 2000, MotionEvent.ACTION_UP, 11, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| // Slide within a candidate (bottom-right corner). |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| candidateSelectListener.onCandidateSelected( |
| ROW_DATA.get(0).getSpanList().get(0).getCandidateWord().get(), Optional.<Integer>of(0)); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 29, 27, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_MOVE, 29, 29, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 2000, MotionEvent.ACTION_UP, 29, 28, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| // Slide out of a candidate. No selection. |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 29, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_MOVE, 30, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 2000, MotionEvent.ACTION_UP, 30, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| // Slide out of a candidate, then come back and release. No selection. |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 29, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_MOVE, 30, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 2000, MotionEvent.ACTION_MOVE, 29, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 3000, MotionEvent.ACTION_UP, 29, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| // Must consider scroll value. |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| candidateWordView.scrollTo(0, -5); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 10, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_UP, 10, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| replayAll(); |
| candidateWordView.scrollTo(-5, 0); |
| events.add(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 10, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| events.add(MotionEvent.obtain(0, 1000, MotionEvent.ACTION_UP, 10, 10, 0)); |
| assertTrue(candidateWordView.onTouchEvent(events.get(events.size() - 1))); |
| verifyAll(); |
| } finally { |
| for (MotionEvent event : events) { |
| event.recycle(); |
| } |
| } |
| } |
| |
| @SmallTest |
| public void testUpdate_noLayouter() { |
| CandidateWordView candidateWordView = new StubCandidateWordView( |
| getInstrumentation().getTargetContext(), Orientation.VERTICAL); |
| assertNull(candidateWordView.getCandidateLayouter()); |
| candidateWordView.update(CANDIDATE_LIST); |
| assertEquals(CANDIDATE_LIST, candidateWordView.currentCandidateList); |
| assertNull(candidateWordView.calculatedLayout); |
| } |
| |
| @SmallTest |
| public void testUpdate_successPath() { |
| CandidateWordView candidateWordView = new StubCandidateWordView( |
| getInstrumentation().getTargetContext(), Orientation.VERTICAL); |
| CandidateLayouter layouter = createMock(CandidateLayouter.class); |
| expect(layouter.layout(isA(CandidateList.class))) |
| .andReturn(Optional.of(MozcLayoutUtil.createNiceCandidateLayoutMock(getMockSupport()))); |
| candidateWordView.layouter = layouter; |
| expect(layouter.getPageHeight()).andReturn(50); |
| replayAll(); |
| |
| candidateWordView.updateLayouter(); |
| assertNotNull(candidateWordView.layouter); // Pre-condition |
| candidateWordView.update(CANDIDATE_LIST); |
| |
| verifyAll(); |
| assertEquals(CANDIDATE_LIST, candidateWordView.currentCandidateList); |
| assertNotNull(candidateWordView.calculatedLayout); |
| } |
| |
| @SmallTest |
| public void testUpdate_identicalOutput() { |
| CandidateWordView candidateWordView = new StubCandidateWordView( |
| getInstrumentation().getTargetContext(), Orientation.VERTICAL); |
| CandidateLayouter layouter = createMock(CandidateLayouter.class); |
| expect(layouter.layout(isA(CandidateList.class))) |
| .andStubReturn(Optional.of(MozcLayoutUtil.createNiceCandidateLayoutMock(getMockSupport()))); |
| expect(layouter.getPageHeight()).andStubReturn(50); |
| candidateWordView.layouter = layouter; |
| replayAll(); |
| |
| candidateWordView.updateLayouter(); |
| assertNotNull(candidateWordView.layouter); // Pre-condition |
| // If the same CandidateList is passed, post-condition should not be changed. |
| candidateWordView.update(CANDIDATE_LIST); |
| candidateWordView.update(CANDIDATE_LIST); |
| |
| verifyAll(); |
| assertEquals(CANDIDATE_LIST, candidateWordView.currentCandidateList); |
| assertNotNull(candidateWordView.calculatedLayout); |
| } |
| |
| @SmallTest |
| public void testUpdate_null() { |
| CandidateWordView candidateWordView = new StubCandidateWordView( |
| getInstrumentation().getTargetContext(), Orientation.VERTICAL); |
| CandidateLayouter layouter = createMock(CandidateLayouter.class); |
| expect(layouter.layout(isA(CandidateList.class))) |
| .andStubReturn(Optional.of(MozcLayoutUtil.createNiceCandidateLayoutMock(getMockSupport()))); |
| expect(layouter.getPageHeight()).andReturn(50); |
| candidateWordView.layouter = layouter; |
| |
| replayAll(); |
| |
| candidateWordView.updateLayouter(); |
| assertNotNull(candidateWordView.layouter); |
| candidateWordView.update(CANDIDATE_LIST); |
| |
| // Pre-condition |
| verifyAll(); |
| assertNotNull(candidateWordView.calculatedLayout); |
| |
| resetAll(); |
| replayAll(); |
| |
| // Update with null should reset calculatedLayout. |
| candidateWordView.update(null); |
| |
| verifyAll(); |
| assertNull(candidateWordView.calculatedLayout); |
| } |
| |
| @SmallTest |
| public void testGetUpdatedScrollPosition() { |
| class TestData extends Parameter { |
| final float candidatePosition; |
| final int scrollPosition; |
| final float candidateLength; |
| final int viewLength; |
| final int expected; |
| |
| TestData(int scrollPosition, float candidatePosition, float candidateLength, int viewLength, |
| int expected) { |
| this.scrollPosition = scrollPosition; |
| this.candidatePosition = candidatePosition; |
| this.candidateLength = candidateLength; |
| this.viewLength = viewLength; |
| this.expected = expected; |
| } |
| } |
| TestData[] testDataList = { |
| // Should scroll to forward direction. |
| new TestData(100, 50, 0, 0, 50), |
| // Should scroll to backward direction. |
| new TestData(0, 50, 100, 100, 50), |
| // Stay here. |
| new TestData(50, 50, 100, 100, 50), |
| new TestData(0, 0, 0, 0, 0), |
| }; |
| |
| CandidateWordView.OrientationTrait trait = |
| createMock(CandidateWordView.OrientationTrait.class); |
| CandidateWordView candidateWordView = new StubCandidateWordView( |
| getInstrumentation().getTargetContext(), trait); |
| for (TestData testData : testDataList) { |
| Row row = new Row(); |
| Span span = MozcLayoutUtil.createEmptySpan(); |
| |
| resetAll(); |
| expect(trait.getScrollPosition(candidateWordView)).andReturn(testData.scrollPosition); |
| expect(trait.getCandidatePosition(row, span)).andReturn(testData.candidatePosition); |
| expect(trait.getCandidateLength(row, span)).andReturn(testData.candidateLength); |
| expect(trait.getViewLength(candidateWordView)).andStubReturn(testData.viewLength); |
| replayAll(); |
| assertEquals( |
| testData.toString(), |
| testData.expected, |
| candidateWordView.getUpdatedScrollPosition(row, span)); |
| verifyAll(); |
| } |
| } |
| |
| @SmallTest |
| public void testUpdateScrollPositionBasedOnFocusedIndex() { |
| SnapScroller scroller = createMock(SnapScroller.class); |
| OrientationTrait trait = createMock(CandidateWordView.OrientationTrait.class); |
| CandidateWordView candidateWordView = new StubCandidateWordView( |
| getInstrumentation().getTargetContext(), trait); |
| VisibilityProxy.setField(candidateWordView, "scroller", scroller); |
| candidateWordView.currentCandidateList = |
| CandidateList.newBuilder().setFocusedIndex(Integer.MAX_VALUE).build(); |
| CandidateLayout mockLayout = MozcLayoutUtil.createCandidateLayoutMock(getMockSupport()); |
| |
| // No layout is set |
| scroller.scrollTo(0); |
| expect(scroller.getScrollPosition()).andReturn(0); |
| trait.scrollTo(same(candidateWordView), eq(0)); |
| replayAll(); |
| candidateWordView.updateScrollPositionBasedOnFocusedIndex(); |
| verifyAll(); |
| |
| // No correspoinding candidate |
| resetAll(); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| scroller.scrollTo(0); |
| expect(scroller.getScrollPosition()).andReturn(0); |
| trait.scrollTo(same(candidateWordView), eq(0)); |
| replayAll(); |
| candidateWordView.calculatedLayout = mockLayout; |
| candidateWordView.scrollTo(100, 100); |
| candidateWordView.updateScrollPositionBasedOnFocusedIndex(); |
| verifyAll(); |
| |
| // Correspoinding candidate is found |
| candidateWordView.currentCandidateList = |
| CandidateList.newBuilder().setFocusedIndex(0).build(); |
| resetAll(); |
| expect(trait.getScrollPosition(candidateWordView)).andStubReturn(0); |
| expect(trait.getCandidatePosition(isA(Row.class), isA(Span.class))).andReturn(0f); |
| expect(trait.getCandidateLength(isA(Row.class), isA(Span.class))).andReturn(0f); |
| expect(trait.getViewLength(candidateWordView)).andReturn(0); |
| expect(mockLayout.getRowList()).andStubReturn(ROW_DATA); |
| scroller.scrollTo(anyInt()); |
| expect(scroller.getScrollPosition()).andReturn(10); |
| trait.scrollTo(same(candidateWordView), eq(10)); |
| replayAll(); |
| candidateWordView.calculatedLayout = mockLayout; |
| candidateWordView.updateScrollPositionBasedOnFocusedIndex(); |
| verifyAll(); |
| } |
| |
| @SuppressLint("WrongCall") |
| @SmallTest |
| public void testOnLayout() { |
| CandidateWordView candWordView = new StubCandidateWordView( |
| getInstrumentation().getTargetContext(), Orientation.VERTICAL); |
| CandidateLayouter layouter = createMock(CandidateLayouter.class); |
| candWordView.layouter = layouter; |
| replayAll(); |
| |
| // Check pre-condition. |
| assertNull(candWordView.calculatedLayout); |
| assertNull(candWordView.currentCandidateList); |
| |
| verifyAll(); |
| |
| // Call onLayout with empty view size. |
| resetAll(); |
| expect(layouter.setViewSize(0, 0)).andReturn(false); |
| replayAll(); |
| |
| candWordView.currentCandidateList = CANDIDATE_LIST; |
| candWordView.onLayout(true, 0, 0, 0, 0); |
| |
| verifyAll(); |
| assertNull(candWordView.calculatedLayout); |
| assertNotNull(candWordView.currentCandidateList); |
| |
| // Call onLayout with non-empty view size. |
| resetAll(); |
| expect(layouter.setViewSize(320, 240)).andReturn(true); |
| expect(layouter.layout(same(CANDIDATE_LIST))) |
| .andReturn(Optional.of(MozcLayoutUtil.createNiceCandidateLayoutMock(getMockSupport()))); |
| expect(layouter.getPageHeight()).andReturn(50); |
| replayAll(); |
| |
| candWordView.onLayout(true, 0, 0, 320, 240); |
| |
| verifyAll(); |
| assertNotNull(candWordView.calculatedLayout); |
| assertNotNull(candWordView.currentCandidateList); |
| } |
| } |