1/* 2 * Copyright (C) 2017 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 com.android.setupwizardlib.template; 18 19import static org.mockito.Matchers.anyInt; 20import static org.mockito.Matchers.eq; 21import static org.mockito.Mockito.doNothing; 22import static org.mockito.Mockito.doReturn; 23import static org.mockito.Mockito.spy; 24import static org.mockito.Mockito.verify; 25import static org.robolectric.RuntimeEnvironment.application; 26 27import android.content.Context; 28import android.view.View; 29import android.view.ViewGroup; 30import android.widget.AbsListView.OnScrollListener; 31import android.widget.BaseAdapter; 32import android.widget.ListView; 33 34import com.android.setupwizardlib.robolectric.SuwLibRobolectricTestRunner; 35 36import org.junit.Before; 37import org.junit.Test; 38import org.junit.runner.RunWith; 39import org.mockito.ArgumentCaptor; 40import org.mockito.Mock; 41import org.mockito.MockitoAnnotations; 42import org.robolectric.annotation.Config; 43 44@Config(sdk = { Config.OLDEST_SDK, Config.NEWEST_SDK }) 45@RunWith(SuwLibRobolectricTestRunner.class) 46public class ListViewScrollHandlingDelegateTest { 47 48 @Mock 49 private RequireScrollMixin mRequireScrollMixin; 50 51 private ListView mListView; 52 private ListViewScrollHandlingDelegate mDelegate; 53 private ArgumentCaptor<OnScrollListener> mListenerCaptor; 54 55 @Before 56 public void setUp() throws Exception { 57 MockitoAnnotations.initMocks(this); 58 59 mListView = spy(new TestListView(application)); 60 mDelegate = new ListViewScrollHandlingDelegate(mRequireScrollMixin, mListView); 61 62 mListenerCaptor = ArgumentCaptor.forClass(OnScrollListener.class); 63 doNothing().when(mListView).setOnScrollListener(mListenerCaptor.capture()); 64 65 mListView.layout(0, 0, 50, 50); 66 } 67 68 @Test 69 public void testRequireScroll() throws Throwable { 70 mDelegate.startListening(); 71 72 verify(mRequireScrollMixin).notifyScrollabilityChange(true); 73 } 74 75 @Test 76 public void testScrolledToBottom() throws Throwable { 77 mDelegate.startListening(); 78 79 verify(mRequireScrollMixin).notifyScrollabilityChange(true); 80 81 doReturn(20).when(mListView).getLastVisiblePosition(); 82 mListenerCaptor.getValue().onScroll(mListView, 2, 20, 20); 83 84 verify(mRequireScrollMixin).notifyScrollabilityChange(false); 85 } 86 87 @Test 88 public void testPageScrollDown() throws Throwable { 89 mDelegate.pageScrollDown(); 90 verify(mListView).smoothScrollBy(eq(50), anyInt()); 91 } 92 93 private static class TestListView extends ListView { 94 95 TestListView(Context context) { 96 super(context); 97 setAdapter(new BaseAdapter() { 98 @Override 99 public int getCount() { 100 return 20; 101 } 102 103 @Override 104 public Object getItem(int position) { 105 return null; 106 } 107 108 @Override 109 public long getItemId(int position) { 110 return position; 111 } 112 113 @Override 114 public View getView(int position, View convertView, ViewGroup parent) { 115 return new View(parent.getContext()); 116 } 117 }); 118 } 119 } 120} 121