/* * Copyright 2015 Rayco AraƱa * * 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.raycoarana.baindo.renderer; import android.view.View; import android.widget.AdapterView; import android.widget.BaseAdapter; import com.raycoarana.baindo.BindableSource; import com.raycoarana.baindo.BinderDelegate; import com.raycoarana.baindo.UnbindableCollectorProvider; import com.raycoarana.baindo.WorkDispatcher; import com.raycoarana.baindo.observables.AbstractCollectionProperty; import com.raycoarana.baindo.test.UnitTestSuite; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.powermock.api.mockito.PowerMockito.when; public class AdapterBindTest extends UnitTestSuite { private static final int SOME_VIEW_RES_ID = 42; @Mock private BinderDelegate mBinderDelegate; @Mock private WorkDispatcher mWorkDispatcher; @Mock private BindableSource mBindableSource; @Mock private AdapterFactory<Object> mAdapterFactory; @Mock private UnbindableCollectorProvider mUnbindableCollector; @Mock private AdapterView<BaseAdapter> mSomeAdapterView; @Mock private AbstractCollectionProperty<Object> mSomeCollectionProperty; @Mock private BinderRendererAdapter mBinderRendererAdapter; @Captor private ArgumentCaptor<BaseAdapter> mBaseAdapterArgumentCaptor; private AdapterBind<Object> mAdapterBind; @Test public void shouldBindAdapterToTarget() { givenAnAdapterView(); givenAnAdapterFactory(); givenAnAdapterBind(); whenBindSomeViewToSomeProperty(); thenAdapterViewReceivedBaseAdapter(); } @Test public void shouldUnbindAdpaterFromTarget() { givenAnAdapterView(); givenAnAdapterFactory(); givenAnAdapterBind(); whenBindSomeViewToSomeProperty(); whenUnbind(); thenAdapterViewIsUnbindedFromProperty(); } @Test public void shouldGetAdapterViewFromBindableSource() { givenAnAdapterView(); givenAnAdapterFactory(); givenAnAdapterBind(); whenBindSomeViewResourceToSomeProperty(); thenBindableSourceFindViewByIdIsCalled(); } @Test public void shouldUpdateAdapterWhenCollectionPropertyChanges() { givenAnAdapterView(); givenAnAdapterFactory(); givenAnAdapterBind(); whenBindSomeViewToSomeProperty(); whenPropertyChanges(); thenAdapterIsNotifiedOfChanges(); } @Test(expected = IllegalArgumentException.class) public void shouldFailWhenIncompatibleViewIsUsed() { givenAnIncompatibleView(); givenAnAdapterFactory(); givenAnAdapterBind(); whenBindSomeViewResourceToSomeProperty(); } private void givenAnAdapterView() { when(mBindableSource.findViewById(SOME_VIEW_RES_ID)).thenReturn(mSomeAdapterView); doNothing().when(mSomeAdapterView).setAdapter(mBaseAdapterArgumentCaptor.capture()); when(mSomeAdapterView.getAdapter()).thenAnswer(new Answer<BaseAdapter>() { @Override public BaseAdapter answer(InvocationOnMock invocationOnMock) throws Throwable { return mBaseAdapterArgumentCaptor.getValue(); } }); } private void givenAnIncompatibleView() { when(mBindableSource.findViewById(SOME_VIEW_RES_ID)).thenReturn(mock(View.class)); } private void givenAnAdapterFactory() { when(mAdapterFactory.build(mSomeCollectionProperty)).thenReturn(mBinderRendererAdapter); } private void givenAnAdapterBind() { mAdapterBind = new AdapterBind<>(mBindableSource, mWorkDispatcher, mBinderDelegate, mAdapterFactory, mUnbindableCollector); } private void whenBindSomeViewToSomeProperty() { mAdapterBind.of(mSomeAdapterView).to(mSomeCollectionProperty); } private void whenBindSomeViewResourceToSomeProperty() { mAdapterBind.of(SOME_VIEW_RES_ID).to(mSomeCollectionProperty); } private void whenUnbind() { mAdapterBind.unbind(); } private void whenPropertyChanges() { mAdapterBind.update(mSomeCollectionProperty, null); } private void thenBindableSourceFindViewByIdIsCalled() { verify(mBindableSource).findViewById(SOME_VIEW_RES_ID); } private void thenAdapterViewReceivedBaseAdapter() { verify(mAdapterFactory).build(mSomeCollectionProperty); verify(mBinderRendererAdapter).injectBinderDelegate(mBinderDelegate); verify(mBinderRendererAdapter).injectUnbindableCollectorProvider(mUnbindableCollector); verify(mSomeAdapterView).setAdapter(mBinderRendererAdapter); thenAdapterIsNotifiedOfChanges(); } private void thenAdapterIsNotifiedOfChanges() { verify(mBinderRendererAdapter).notifyDataSetChanged(); } private void thenAdapterViewIsUnbindedFromProperty() { verify(mBinderRendererAdapter).unbind(); } }