Migrate tests from androidTest to app-test!

This commit is contained in:
Bradlee Speice
2014-11-20 00:52:42 -05:00
parent f331f95722
commit e9e6d1dacd
8 changed files with 64 additions and 21 deletions

View File

@ -0,0 +1,219 @@
package org.bspeice.minimalbible.test.activity.downloader.manager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs;
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
import org.crosswire.common.progress.JobManager;
import org.crosswire.common.progress.WorkEvent;
import org.crosswire.common.progress.WorkListener;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.BookDriver;
import org.crosswire.jsword.book.BookException;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.BooksEvent;
import org.crosswire.jsword.book.install.InstallManager;
import org.crosswire.jsword.book.install.Installer;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.ObjectGraph;
import dagger.Provides;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
import static com.jayway.awaitility.Awaitility.await;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;
// TODO: Fix @Ignore'd tests
public class BookManagerTest implements Injector {
ObjectGraph mObjectGraph;
@Inject
BookManager bookManager;
@Inject
RefreshManager refreshManager;
@Inject
Books installedBooks;
@Override
public void inject(Object o) {
mObjectGraph.inject(o);
}
@Before
public void setUp() {
BookDownloadManagerTestModules modules = new BookDownloadManagerTestModules(this);
mObjectGraph = ObjectGraph.create(modules);
mObjectGraph.inject(this);
}
Observable<Book> installableBooks() {
return refreshManager.getFlatModules()
.filter(new Func1<Book, Boolean>() {
@Override
public Boolean call(Book book) {
return !installedBooks.getBooks().contains(book);
}
});
}
@Ignore
public void testInstallBook() throws Exception {
final Book toInstall = installableBooks().toBlocking().first();
bookManager.installBook(toInstall);
final AtomicBoolean signal = new AtomicBoolean(false);
bookManager.getDownloadEvents()
.subscribe(new Action1<DLProgressEvent>() {
@Override
public void call(DLProgressEvent dlProgressEvent) {
if (dlProgressEvent.getB().getInitials().equals(toInstall.getInitials())
&& dlProgressEvent.getProgress() == DLProgressEvent.PROGRESS_COMPLETE) {
signal.set(true);
}
}
});
await().atMost(60, TimeUnit.SECONDS)
.untilTrue(signal);
}
@Ignore
public void testJobIdMatch() {
final Book toInstall = installableBooks().toBlocking().first();
final String jobName = bookManager.getJobId(toInstall);
final AtomicBoolean jobNameMatch = new AtomicBoolean(false);
JobManager.addWorkListener(new WorkListener() {
@Override
public void workProgressed(WorkEvent ev) {
Log.d("testJobIdMatch", ev.getJob().getJobID() + " " + jobName);
if (ev.getJob().getJobID().equals(jobName)) {
jobNameMatch.set(true);
}
}
@Override
public void workStateChanged(WorkEvent ev) {
}
});
bookManager.installBook(toInstall);
await().atMost(5, TimeUnit.SECONDS)
.untilTrue(jobNameMatch);
}
@Test
public void testLocalListUpdatedAfterAdd() {
Book mockBook = mock(Book.class);
BooksEvent event = mock(BooksEvent.class);
when(event.getBook()).thenReturn(mockBook);
bookManager.bookAdded(event);
assertTrue(bookManager.getInstalledBooksList().contains(mockBook));
}
/**
* This test requires deep knowledge of how to remove a book in order to test,
* but the Kotlin interface is nice!
*/
@Test
public void testLocalListUpdatedAfterRemove() throws BookException {
BookDriver driver = mock(BookDriver.class);
Book mockBook = mock(Book.class);
Book secondMockBook = mock(Book.class);
when(mockBook.getDriver()).thenReturn(driver);
BooksEvent event = mock(BooksEvent.class);
when(event.getBook()).thenReturn(mockBook);
bookManager.getInstalledBooksList().add(mockBook);
assertTrue(bookManager.getInstalledBooksList().contains(mockBook));
bookManager.removeBook(mockBook, secondMockBook);
assertFalse(bookManager.getInstalledBooksList().contains(mockBook));
verify(driver, times(1)).delete(secondMockBook);
}
/**
* Modules needed for this test case
*/
@Module(injects = {BookManager.class,
RefreshManager.class,
BookManagerTest.class})
@SuppressWarnings("unused")
public static class BookDownloadManagerTestModules {
Injector i;
ConnectivityManager manager;
DownloadPrefs prefs;
BookDownloadManagerTestModules(Injector i) {
this.i = i;
// Set reasonable defaults for the manager and preferences, can over-ride if need-be
manager = mock(ConnectivityManager.class);
NetworkInfo mockNetworkInfo = Mockito.mock(NetworkInfo.class);
when(manager.getActiveNetworkInfo()).thenReturn(mockNetworkInfo);
when(mockNetworkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI);
prefs = mock(DownloadPrefs.class);
}
@Provides
@Singleton
Books provideBooks() {
return Books.installed();
}
@Provides
@Singleton
Collection<Installer> provideInstallers() {
return new InstallManager().getInstallers().values();
}
void setConnectivityManager(ConnectivityManager manager) {
this.manager = manager;
}
void setPrefs(DownloadPrefs prefs) {
this.prefs = prefs;
}
@Provides
@Singleton
RefreshManager refreshManager(Collection<Installer> installers) {
return new RefreshManager(installers,
prefs, manager);
}
@Provides
@Singleton
BookManager bookDownloadManager(Books installed, RefreshManager rm) {
return new BookManager(installed, rm);
}
}
}

View File

@ -0,0 +1,46 @@
package org.bspeice.minimalbible.test.activity.downloader.manager;
import org.bspeice.minimalbible.activity.downloader.manager.LocaleManager;
import org.crosswire.common.util.Language;
import org.junit.Test;
import java.util.List;
import rx.Observable;
import static org.junit.Assert.assertTrue;
/**
* Test cases for the Locale Manager
*/
public class LocaleManagerTest {
@Test
public void testSortedLanguagesList() {
Language english = new Language("en");
Language russian = new Language("ru");
Language french = new Language("fr");
Language german = new Language("de");
Language hebrew = new Language("he");
Language afrikaans = new Language("af");
Observable<Language> languages = Observable.just(english, russian, french,
german, hebrew, afrikaans);
LocaleManager.Core core = LocaleManager.Core.INSTANCE$;
//noinspection ConstantConditions
List<Language> sortedLanguages = core.sortedLanguagesList(languages, english)
.toBlocking().first();
// First language should be the 'current' (note this is an identity compare)
assertTrue(sortedLanguages.get(0) == english);
// Second language should be 'less than' third
assertTrue(sortedLanguages.toString(),
sortedLanguages.get(1).toString().compareTo(
sortedLanguages.get(2).toString()) < 0);
// Fifth language should be greater than the fourth
assertTrue(sortedLanguages.toString(), sortedLanguages.get(4).toString().compareTo(
sortedLanguages.get(3).toString()) > 0);
}
}

View File

@ -0,0 +1,199 @@
package org.bspeice.minimalbible.test.activity.downloader.manager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs;
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.install.Installer;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.ObjectGraph;
import dagger.Provides;
import rx.functions.Action1;
import static com.jayway.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class RefreshManagerTest implements Injector {
final String mockBookName = "MockBook";
/**
* The object graph that should be given to classes under test. Each test is responsible
* for setting their own ObjectGraph.
*/
ObjectGraph mObjectGraph;
@Inject
RefreshManager rM;
Installer mockInstaller;
Book mockBook;
@Before
public void setUp() {
// Environment setup
mockBook = mock(Book.class);
when(mockBook.getName()).thenReturn(mockBookName);
mockInstaller = mock(Installer.class);
List<Book> bookList = new ArrayList<Book>();
bookList.add(mockBook);
when(mockInstaller.getBooks()).thenReturn(bookList);
Collection<Installer> mockInstallers = new ArrayList<Installer>();
mockInstallers.add(mockInstaller);
RMTModules modules = new RMTModules(mockInstallers);
mObjectGraph = ObjectGraph.create(modules);
// Now the actual test
mObjectGraph.inject(this); // Get the RefreshManager
}
@Override
public void inject(Object o) {
mObjectGraph.inject(o);
}
@Test
public void testGetAvailableModulesFlattened() throws Exception {
rM.getFlatModules()
.toBlocking()
.forEach(new Action1<Book>() {
@Override
public void call(Book book) {
assertEquals(mockBookName, book.getName());
}
});
verify(mockInstaller).getBooks();
verify(mockBook).getName();
}
@Test
public void testInstallerFromBook() throws Exception {
Installer i = rM.installerFromBook(mockBook).toBlocking().first();
assertSame(mockInstaller, i);
verify(mockInstaller).getBooks();
}
@Test
public void testRefreshSeparateThread() {
mockInstaller = mock(Installer.class);
final List<Book> bookList = new ArrayList<Book>();
when(mockInstaller.getBooks()).thenAnswer(new Answer<List<Book>>() {
@Override
public List<Book> answer(InvocationOnMock invocationOnMock) throws Throwable {
Thread.sleep(1000); // Just long enough to give us a gap between
// refresh start and complete
return bookList;
}
});
Collection<Installer> mockInstallers = new ArrayList<Installer>();
mockInstallers.add(mockInstaller);
RMTModules modules = new RMTModules(mockInstallers);
mObjectGraph = ObjectGraph.create(modules);
// And the actual test
mObjectGraph.inject(this);
// So the refresh should be kicked off at the constructor, meaning that it's not "complete"
assertFalse(rM.getRefreshComplete().get());
// But, if it's on another thread, it should finish up eventually, right?
await().atMost(5, TimeUnit.SECONDS).until(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return rM.getRefreshComplete().get();
}
});
}
/**
* Test the conditions are right for downloading
* I'd like to point out that I can test all of this without requiring mocking of
* either the preferences or network state. Value Boundaries for the win.
*/
@Test
public void testDoUpdate() {
long fourteenDaysAgo = Calendar.getInstance().getTime().getTime() - 1209600;
long sixteenDaysAgo = Calendar.getInstance().getTime().getTime() - 1382400;
assertFalse(rM.doReload(true, fourteenDaysAgo, ConnectivityManager.TYPE_DUMMY));
assertFalse(rM.doReload(true, fourteenDaysAgo, ConnectivityManager.TYPE_WIFI));
assertFalse(rM.doReload(true, sixteenDaysAgo, ConnectivityManager.TYPE_DUMMY));
assertTrue(rM.doReload(true, sixteenDaysAgo, ConnectivityManager.TYPE_WIFI));
assertFalse(rM.doReload(false, fourteenDaysAgo, ConnectivityManager.TYPE_WIFI));
assertFalse(rM.doReload(false, fourteenDaysAgo, ConnectivityManager.TYPE_DUMMY));
assertFalse(rM.doReload(false, sixteenDaysAgo, ConnectivityManager.TYPE_WIFI));
assertFalse(rM.doReload(false, sixteenDaysAgo, ConnectivityManager.TYPE_DUMMY));
}
@Module(injects = {RefreshManagerTest.class, RefreshManager.class})
@SuppressWarnings("unused")
class RMTModules {
Collection<Installer> installers;
ConnectivityManager manager;
DownloadPrefs prefs;
RMTModules(Collection<Installer> installers) {
this.installers = installers;
// Set reasonable defaults for the manager and preferences, can over-ride if need-be
manager = mock(ConnectivityManager.class);
NetworkInfo mockNetworkInfo = Mockito.mock(NetworkInfo.class);
when(manager.getActiveNetworkInfo()).thenReturn(mockNetworkInfo);
when(mockNetworkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI);
prefs = mock(DownloadPrefs.class);
}
@Provides
@Singleton
Collection<Installer> provideInstallers() {
return this.installers;
}
void setConnectivityManager(ConnectivityManager manager) {
this.manager = manager;
}
void setPrefs(DownloadPrefs prefs) {
this.prefs = prefs;
}
@Provides
@Singleton
RefreshManager refreshManager(Collection<Installer> installers) {
return new RefreshManager(installers,
prefs, manager);
}
}
}

View File

@ -0,0 +1,85 @@
package org.bspeice.minimalbible.test.format.osisparser;
import android.annotation.SuppressLint;
import org.bspeice.minimalbible.service.format.osisparser.OsisParser;
import org.crosswire.jsword.book.OSISUtil;
import org.crosswire.jsword.passage.Verse;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.xml.sax.Attributes;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
/**
* State machine testing, oh boy!
*/
public class OsisParserTest {
OsisParser parser;
@Before
public void setUp() {
parser = new OsisParser();
}
@SuppressLint("NewApi")
@Test
public void testDoWriteEnabledVerse() {
Attributes attributes = mock(Attributes.class);
parser.startElement("", OSISUtil.OSIS_ELEMENT_VERSE, "", attributes);
assertTrue(parser.getDoWrite().peek());
}
@SuppressLint("NewApi")
private void parserAssert(OsisParser parser, String element) {
Attributes attributes = mock(Attributes.class);
parser.startElement("", element, "", attributes);
assertFalse(parser.getDoWrite().isEmpty());
parser.getDoWrite().pop();
}
@Test
public void testDoWriteAlwaysAdded() {
parserAssert(parser, OSISUtil.OSIS_ELEMENT_VERSE);
parserAssert(parser, "");
parserAssert(parser, "random string");
parserAssert(parser, OSISUtil.OSIS_ELEMENT_CELL);
}
@SuppressLint("NewApi")
@Test
public void testEndElementPopsQueue() {
parser.getDoWrite().add(true);
parser.endElement("", "", "");
assertTrue(parser.getDoWrite().isEmpty());
}
// During initial development, I accidentally set up the verseContent
// as a value computed every time - so you'd get a new "content" every time
// you tried to update it. Thus, if you updated the content only once, you're fine.
// Try and update multiple times, and things would start going crazy.
// TODO: Why is this ignored?
@SuppressLint("NewApi")
@SuppressWarnings("unused")
@Ignore
public void ignoreTestVerseContentConsistent() {
String string1 = "1";
String string2 = "2";
// Yes, I need intimate knowledge of the state machine to run this test
// Also, Verse is final, so I can't mock that, which is why this test is ignored.
Verse mockVerse = mock(Verse.class);
parser.setVerse(mockVerse);
parser.getDoWrite().push(true);
parser.characters(string1.toCharArray(), 0, string1.length());
assertEquals(parser.getVerseContent().getContent(), string1);
parser.characters(string2.toCharArray(), 0, string2.length());
assertEquals(parser.getVerseContent().getContent(), string1 + string2);
}
}