Plenty o' updates: Kotlin 12, new JSword build

This commit is contained in:
Bradlee Speice
2015-06-13 19:22:21 -04:00
parent 90f50e37f4
commit e756ec8c28
97 changed files with 1939 additions and 439 deletions

159
app/app.iml Normal file
View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="MinimalBible" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":app" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="SELECTED_TEST_ARTIFACT" value="_unit_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugUnitTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugUnitTestSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res;file://$MODULE_DIR$/src/debug/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/kapt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/cardview-v7/22.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/22.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.orhanobut/logger/1.10/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" scope="TEST" name="robolectric-resources-3.0-rc3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="mockito-core-2.0.14-beta" level="project" />
<orderEntry type="library" exported="" name="xz-1.4" level="project" />
<orderEntry type="library" exported="" name="lucene-analyzers-3.0.3" level="project" />
<orderEntry type="library" exported="" name="dagger-compiler-1.2.2" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="objenesis-2.1" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-library-1.3" level="project" />
<orderEntry type="library" exported="" name="commons-compress-1.7" level="project" />
<orderEntry type="library" exported="" name="esperandro-2.2.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="bcprov-jdk16-1.46" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="shadows-core-3.0-rc3" level="project" />
<orderEntry type="library" exported="" name="kotlin-stdlib-0.12.213" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.0.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="asm-tree-5.0.1" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="robolectric-annotations-3.0-rc3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="asm-analysis-5.0.1" level="project" />
<orderEntry type="library" exported="" name="esperandro-api-2.2.0" level="project" />
<orderEntry type="library" exported="" name="cardview-v7-22.0.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="robolectric-utils-3.0-rc3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="icu4j-53.1" level="project" />
<orderEntry type="library" exported="" name="httpcore-4.3.2" level="project" />
<orderEntry type="library" exported="" name="lucene-smartcn-3.0.3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="ant-launcher-1.8.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="byte-buddy-0.6.8" level="project" />
<orderEntry type="library" exported="" name="commons-lang3-3.4" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="asm-util-5.0.1" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="awaitility-1.6.3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="spek-0.1.165" level="project" />
<orderEntry type="library" exported="" name="guava-15.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="asm-5.0.1" level="project" />
<orderEntry type="library" exported="" name="dagger-1.2.2" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="cglib-nodep-3.1" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="ant-1.8.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="robolectric-3.0-rc3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="accessibility-test-framework-1.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.0.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="sqlite4java-0.282" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="maven-ant-tasks-2.1.3" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-22.0.0" level="project" />
<orderEntry type="library" exported="" name="rxjava-core-0.20.7" level="project" />
<orderEntry type="library" exported="" name="acra-4.6.2" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="mockable-android-22" level="project" />
<orderEntry type="library" exported="" name="logger-1.10" level="project" />
<orderEntry type="library" exported="" name="annotations-4.1.1.4" level="project" />
<orderEntry type="library" exported="" name="lucene-snowball-3.0.3" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.0.0" level="project" />
<orderEntry type="library" exported="" name="systembartint-1.0.4" level="project" />
<orderEntry type="library" exported="" name="lucene-core-3.0.3" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="vtd-xml-2.11" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="asm-commons-5.0.1" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
<orderEntry type="library" exported="" name="butterknife-6.1.0" level="project" />
<orderEntry type="library" exported="" name="slf4j-api-1.7.6" level="project" />
<orderEntry type="library" exported="" name="rxjava-android-0.20.7" level="project" />
<orderEntry type="library" exported="" name="javax.inject-1" level="project" />
<orderEntry type="library" exported="" name="javawriter-2.5.1" level="project" />
<orderEntry type="library" exported="" name="kotlin-runtime-0.12.213" level="project" />
<orderEntry type="library" exported="" name="commons-net-3.3" level="project" />
<orderEntry type="library" exported="" name="jdom2-2.0.5" level="project" />
<orderEntry type="module" module-name="jsword-minimalbible" scope="TEST" />
</component>
</module>

View File

@ -1,6 +1,7 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
@ -8,6 +9,12 @@ buildscript {
}
}
repositories {
maven {
url "http://repository.jetbrains.com/all"
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'play'
@ -54,6 +61,7 @@ android {
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
test.java.srcDirs += 'src/test/kotlin'
}
}
@ -63,7 +71,7 @@ play {
}
dependencies {
compile project(path: ':jsword-minimalbible', configuration: 'buildJSword')
compile project(':jsword-minimalbible')
compile 'com.squareup.dagger:dagger:+'
provided 'com.squareup.dagger:dagger-compiler:+'
@ -80,9 +88,16 @@ dependencies {
compile 'com.orhanobut:logger:+'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// Instrumentation Test dependencies
androidTestCompile 'com.jayway.awaitility:awaitility:+'
androidTestCompile 'org.mockito:mockito-core:+'
// Unit Test dependencies
testCompile 'junit:junit:4.12'
testCompile 'com.jayway.awaitility:awaitility:+'
testCompile 'org.mockito:mockito-core:+'
testCompile 'org.jetbrains.spek:spek:+'
// Email debug reports if I crash...
debugCompile('ch.acra:acra:+') {
exclude module: 'json'

View File

@ -0,0 +1,165 @@
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 java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.ObjectGraph;
import dagger.Provides;
import rx.functions.Action1;
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 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
List<String> excludeList() {
return new ArrayList<>();
}
@Provides
@Singleton
RefreshManager refreshManager(Collection<Installer> installers, List<String> excludes) {
return new RefreshManager(installers, excludes,
prefs, manager);
}
}
}

View File

@ -0,0 +1,25 @@
package org.bspeice.minimalbible
import org.junit.Before
import org.junit.Test
import kotlin.properties.Delegates
class SafeValDelegateKotlinTest {
var delegate: SafeValDelegate<String> by Delegates.notNull()
Before fun setUp() {
delegate = SafeValDelegate()
}
Test(expected = IllegalStateException::class)
fun testDelegateNullSafety() {
delegate.get(null, PropertyMetadataImpl(""))
}
Test(expected = IllegalStateException::class)
fun testDelegateAssignOnce() {
delegate.set(null, PropertyMetadataImpl(""), "")
delegate.set(null, PropertyMetadataImpl(""), "")
}
}

View File

@ -0,0 +1,82 @@
package org.bspeice.minimalbible.activity.downloader
import android.content.DialogInterface
import org.jetbrains.spek.api.Spek
import kotlin.test.assertTrue
/**
* Created by bspeice on 11/22/14.
*/
class BookListFragmentSpek : Spek() {init {
given("A BookListFragment with showDialog() mocked out") {
val fragment = object : BookListFragment() {
var condition = false
override fun showDialog() {
condition = true
}
}
on("attempting to display modules with the dialog not shown already") {
fragment.displayModules(false)
it("should show the download dialog") {
assertTrue(fragment.condition)
}
}
}
given("a BookListFragment with displayLanguageSpinner() mocked out") {
val fragment = object : BookListFragment() {
var condition = false
override fun displayLanguageSpinner() {
condition = true
}
}
on("attempting to display modules with the dialog already shown") {
fragment.displayModules(true)
it("should show the available languages spinner") {
assertTrue(fragment.condition)
}
}
}
given("a DownloadDialogListener with with buttonPositive() mocked out") {
val listener = object : BookListFragment.DownloadDialogListener(null, null) {
var condition = false
override fun buttonPositive() {
condition = true
}
}
on("handling a positive button press") {
listener.handleButton(DialogInterface.BUTTON_POSITIVE)
it("should call the proper handler") {
assertTrue(listener.condition)
}
}
}
given("A DownloadDialogListener with buttonNegative() mocked out") {
val listener = object : BookListFragment.DownloadDialogListener(null, null) {
var condition = false
override fun buttonNegative() {
condition = true
}
}
on("handling a negative button press") {
listener.handleButton(DialogInterface.BUTTON_NEGATIVE)
it("should call the proper handler") {
assertTrue(listener.condition)
}
}
}
}
}

View File

@ -0,0 +1,27 @@
/**
* Created by bspeice on 11/20/14.
*/
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent
import org.crosswire.jsword.book.Book
import org.jetbrains.spek.api.Spek
import org.mockito.Mockito.mock
import kotlin.test.assertEquals
class DLProgressEventSpek : Spek() {init {
given("a DLProgressEvent created with 50% progress and a mock book") {
val mockBook = mock(javaClass<Book>())
val dlEvent = DLProgressEvent(50, mockBook)
on("getting the progress in degrees") {
val progressDegrees = dlEvent.toCircular()
it("should be 180 degrees") {
assertEquals(180, progressDegrees)
}
}
}
}
}

View File

@ -0,0 +1,66 @@
package org.bspeice.minimalbible.activity.downloader.manager
import org.crosswire.common.util.Language
import org.jetbrains.spek.api.Spek
/**
* Created by bspeice on 12/14/14.
*/
class LocaleManagerSpek() : Spek() {init {
given("some example language objects") {
val english = Language("en")
val russian = Language("ru")
val french = Language("fr");
on("sorting between english and russian with current as english") {
val result = LocaleManager.compareLanguages(english, russian, english)
it("should prioritize english") {
assert(result < 0)
}
}
on("sorting between russian and english with current as english") {
val result = LocaleManager.compareLanguages(russian, english, english)
it("should prioritize english") {
assert(result > 0)
}
}
on("sorting between russian and english with current as french") {
val result = LocaleManager.compareLanguages(russian, english, french)
it("should inform us that russian is greater") {
assert(result > 0)
}
}
on("sorting between english and russian with current as french") {
val result = LocaleManager.compareLanguages(english, russian, french)
it("should inform us that english is lesser") {
assert(result < 0)
}
}
on("comparing the same languages with current language as the language being compared") {
val result = LocaleManager.compareLanguages(english, english, english)
it("should report that the languages are duplicate") {
assert(result == 0)
}
}
on("comparing the same languages with current language as something different") {
val result = LocaleManager.compareLanguages(english, english, russian)
it("should report that the languages are duplicate") {
assert(result == 0)
}
}
}
}
}

View File

@ -0,0 +1,108 @@
package org.bspeice.minimalbible.activity.downloader.manager
import com.jayway.awaitility.Awaitility
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs
import org.crosswire.jsword.book.Book
import org.crosswire.jsword.book.install.Installer
import org.jetbrains.spek.api.Spek
import org.mockito.Matchers.anyLong
import org.mockito.Mockito.*
import rx.Subscriber
import rx.schedulers.Schedulers
import java.util.Calendar
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
/**
* Created by bspeice on 1/3/15.
*/
class RefreshManagerSpek() : Spek() {init {
fun buildRefreshmanager(installers: List<Installer>, prefs: DownloadPrefs) =
RefreshManager(installers, listOf(""), prefs, null)
fun buildMockPrefs(): DownloadPrefs {
val currentTime = Calendar.getInstance().getTime().getTime()
val eighteenDaysAgo = currentTime - 1555200
val mockPrefs = mock(javaClass<DownloadPrefs>())
`when`(mockPrefs.downloadRefreshedOn())
.thenReturn(eighteenDaysAgo)
return mockPrefs
}
given("a mock installer") {
val installer = mock(javaClass<Installer>())
on("creating a new RefreshManager and mock preferences") {
val mockPrefs = buildMockPrefs()
buildRefreshmanager(listOf(installer, installer), mockPrefs)
it("should not have updated the prefs as part of the constructor") {
verify(mockPrefs, never())
.downloadRefreshedOn(anyLong())
}
}
on("creating a new RefreshManager and mock preferences") {
val mockPrefs = buildMockPrefs()
val rM = buildRefreshmanager(listOf(installer, installer), mockPrefs)
reset(mockPrefs)
it("should not update the prefs after the first installer") {
// The process to do actually validate this is tricky. We have to block
// the Observable from producing before we can validate the preferences -
// I don't want to race the Observable since it's possible it's on another thread.
// So, we use backpressure (request(1)) to force the observable to
// produce only one result.
val success = AtomicBoolean(false)
rM.availableModules
.subscribe(object : Subscriber<Map<Installer, List<Book>>>() {
override fun onCompleted() {
}
override fun onError(e: Throwable?) {
}
override fun onStart() {
super.onStart()
request(1)
}
override fun onNext(t: Map<Installer, List<Book>>?) {
// Verify the mock - if verification doesn't pass, we won't reach
// the end of this method and set our AtomicBoolean to true
verify(mockPrefs, never())
.downloadRefreshedOn(anyLong())
success.set(true)
}
})
Awaitility.waitAtMost(2, TimeUnit.SECONDS)
.untilTrue(success)
}
}
on("creating a new RefreshManager and mock preferences") {
val mockPrefs = buildMockPrefs()
val rM = buildRefreshmanager(listOf(installer, installer), mockPrefs)
reset(mockPrefs)
it("should update the prefs after completed") {
val complete = AtomicBoolean(false)
rM.availableModules.observeOn(Schedulers.immediate())
.subscribe({}, {}, {
complete.set(true)
})
Awaitility.waitAtMost(3, TimeUnit.SECONDS)
.untilTrue(complete)
verify(mockPrefs, times(1))
.downloadRefreshedOn(anyLong())
}
}
}
}
}

View File

@ -0,0 +1,187 @@
package org.bspeice.minimalbible.activity.search
import com.jayway.awaitility.Awaitility
import org.crosswire.jsword.book.Book
import org.crosswire.jsword.index.IndexManager
import org.crosswire.jsword.index.IndexStatus
import org.jetbrains.spek.api.Spek
import org.mockito.Mockito
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import kotlin.test.fail
/**
* Created by bspeice on 2/16/15.
*/
data class Mocks() {
val mockBook = Mockito.mock(javaClass<Book>())
val mockIndex = Mockito.mock(javaClass<IndexManager>())
val indexManager = MBIndexManager(mockIndex)
}
class MBIndexManagerSpek() : Spek() {init {
given("a mock IndexManager, Book, and real MBIndexManager") {
val mocks = Mocks()
val mockBook = mocks.mockBook
val indexManager = mocks.indexManager
val firstStatus = IndexStatus.UNDONE
val secondStatus = IndexStatus.DONE
on("setting up the book and attempting to create the index") {
val firstNext = AtomicReference<IndexStatus>()
val secondNext = AtomicReference<IndexStatus>()
val completedReference = AtomicBoolean(false)
Mockito.`when`(mockBook.getIndexStatus())
// MBIndexManager checks status
.thenReturn(firstStatus)
// First actual status
.thenReturn(firstStatus)
// Second actual status
.thenReturn(secondStatus)
val subject = indexManager.buildIndex(mockBook)
subject.subscribe({
if (firstNext.get() == null)
firstNext.set(it)
else
secondNext.set(it)
},
{},
{ completedReference.set(true) })
// Wait until completed
Awaitility.waitAtMost(1, TimeUnit.SECONDS).untilTrue(completedReference);
it("should fire the correct first status") {
assertEquals(firstStatus, firstNext.get())
}
it("should fire the correct second status") {
assertEquals(secondStatus, secondNext.get())
}
it("should fire the onCompleted event") {
assertTrue(completedReference.get())
}
}
}
given("a mock IndexManager, Book, and real MBIndexManager") {
val mocks = Mocks()
val indexManager = mocks.mockIndex
val book = mocks.mockBook
val mbIndex = mocks.indexManager
on("trying to remove a book's index") {
mbIndex.removeIndex(book)
it("should call the IndexManager.deleteIndex() function") {
Mockito.verify(indexManager, Mockito.times(1)) deleteIndex book
}
}
}
given("a Book that is indexed and real MBIndexManager") {
val mocks = Mocks()
val book = mocks.mockBook
val indexManager = mocks.indexManager
Mockito.`when`(book.getIndexStatus())
.thenReturn(IndexStatus.DONE)
on("trying to determine whether we should index") {
it("should not try to index") {
assertFalse(indexManager shouldIndex book)
}
}
on("trying to determine if an index is ready") {
it("should let us know that everything is ready") {
assertTrue(indexManager indexReady book)
}
}
on("attempting to index anyway") {
it("should throw an error") {
try {
indexManager buildIndex book
fail()
} catch (e: IllegalStateException) {
// Intentionally empty body
}
}
}
}
given("a Book with an indexing error") {
val mocks = Mocks()
val book = mocks.mockBook
val mockIndex = mocks.mockIndex
val indexManager = mocks.indexManager
Mockito.`when`(book.getIndexStatus())
.thenReturn(IndexStatus.INVALID)
on("trying to determine whether we should index") {
it("should try to index again and over-write the original") {
assertTrue(indexManager shouldIndex book)
}
}
on("trying to determine if an index is ready") {
it("should inform us that the index is most certainly not ready") {
assertFalse(indexManager indexReady book)
}
}
on("attempting to index") {
indexManager buildIndex book
it("should run the index") {
Mockito.verify(mockIndex, Mockito.times(1))
.scheduleIndexCreation(book);
}
}
}
given("a Book in process of being indexed") {
val mocks = Mocks()
val book = mocks.mockBook
val indexManager = mocks.indexManager
Mockito.`when`(book.getIndexStatus())
.thenReturn(IndexStatus.CREATING)
on("trying to determine whether we should index") {
it("should not create a second indexing thread") {
assertFalse(indexManager shouldIndex book)
}
}
on("trying to determine if the index is ready") {
it("should let us know that the index is still in progress") {
assertFalse(indexManager shouldIndex book)
}
}
on("attempting to index anyway") {
it("should throw an error to let us know it will not index") {
try {
indexManager buildIndex book
fail()
} catch (e: IllegalStateException) {
// Intentionally empty body
}
}
}
}
}
}