mirror of
https://github.com/MinimalBible/MinimalBible
synced 2025-07-05 07:44:43 -04:00
Migrate tests from androidTest to app-test!
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user