Replace Mockito with Mokkery
This commit is contained in:
parent
232be1440e
commit
a527389b96
@ -8,7 +8,6 @@ commonsIo = "1.3.2"
|
||||
commonsLang3 = "3.14.0"
|
||||
kotlin-inject = "0.9.0"
|
||||
desugar = "2.1.4"
|
||||
dexmaker = "2.28.3"
|
||||
espresso = "3.6.1"
|
||||
guava = "33.2.1-android"
|
||||
hamcrest = "2.2"
|
||||
@ -25,7 +24,7 @@ ktor = "1.6.8"
|
||||
ktxCoroutine = "1.10.1"
|
||||
legacy-support = "1.0.0"
|
||||
material = "1.12.0"
|
||||
mockito-kotlin = "5.4.0"
|
||||
mokkery = "2.7.1"
|
||||
opencsv = "5.9"
|
||||
rules = "1.6.1"
|
||||
shadow = "8.1.1"
|
||||
@ -43,7 +42,6 @@ commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "co
|
||||
kotlin-inject-runtime = { group = "me.tatarka.inject", name = "kotlin-inject-runtime", version.ref = "kotlin-inject" }
|
||||
kotlin-inject-compiler = { group = "me.tatarka.inject", name = "kotlin-inject-compiler-ksp", version.ref = "kotlin-inject" }
|
||||
desugar_jdk_libs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "desugar" }
|
||||
dexmaker-mockito = { group = "com.linkedin.dexmaker", name = "dexmaker-mockito", version.ref = "dexmaker" }
|
||||
espresso-contrib = { group = "androidx.test.espresso", name = "espresso-contrib", version.ref = "espresso" }
|
||||
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" }
|
||||
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
|
||||
@ -67,36 +65,16 @@ ktor-jackson = { group = "io.ktor", name = "ktor-jackson", version.ref = "ktor"
|
||||
legacy-preference-v14 = { group = "androidx.legacy", name = "legacy-preference-v14", version.ref = "legacy-support" }
|
||||
legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacy-support" }
|
||||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||
mockito-kotlin = { group = "org.mockito.kotlin", name = "mockito-kotlin", version.ref = "mockito-kotlin" }
|
||||
opencsv = { group = "com.opencsv", name = "opencsv", version.ref = "opencsv" }
|
||||
rules = { group = "androidx.test", name = "rules", version.ref = "rules" }
|
||||
sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" }
|
||||
uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" }
|
||||
documentfile = { group = "androidx.documentfile", name = "documentfile", version.ref = "documentfile" }
|
||||
|
||||
[bundles]
|
||||
androidTest = [
|
||||
"annotation",
|
||||
"kotlin-inject-runtime",
|
||||
"dexmaker-mockito",
|
||||
"espresso-contrib",
|
||||
"espresso-core",
|
||||
"junit",
|
||||
"ktor-client-mock",
|
||||
"ktor-jackson",
|
||||
"mockito-kotlin",
|
||||
"rules",
|
||||
"uiautomator"
|
||||
]
|
||||
test = [
|
||||
"kotlin-inject-runtime",
|
||||
"junit-junit",
|
||||
"mockito-kotlin",
|
||||
]
|
||||
|
||||
[plugins]
|
||||
agp = { id = "com.android.application", version.ref = "agp" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
||||
ktlint-plugin = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint-plugin" }
|
||||
mokkery = { id = "dev.mokkery", version.ref = "mokkery" }
|
||||
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }
|
||||
@ -22,6 +22,7 @@ plugins {
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.ksp)
|
||||
alias(libs.plugins.ktlint.plugin)
|
||||
alias(libs.plugins.mokkery)
|
||||
}
|
||||
|
||||
tasks.compileLint {
|
||||
@ -88,6 +89,10 @@ android {
|
||||
lint.abortOnError = false
|
||||
}
|
||||
|
||||
mokkery {
|
||||
defaultMockMode.set(dev.mokkery.MockMode.autofill)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring(libs.desugar.jdk.libs)
|
||||
implementation(libs.appIntro)
|
||||
@ -111,6 +116,16 @@ dependencies {
|
||||
implementation(project(":uhabits-core"))
|
||||
ksp(libs.kotlin.inject.compiler)
|
||||
|
||||
androidTestImplementation(libs.bundles.androidTest)
|
||||
testImplementation(libs.bundles.test)
|
||||
androidTestImplementation(libs.annotation)
|
||||
androidTestImplementation(libs.kotlin.inject.runtime)
|
||||
androidTestImplementation(libs.espresso.contrib)
|
||||
androidTestImplementation(libs.espresso.core)
|
||||
androidTestImplementation(libs.junit)
|
||||
androidTestImplementation(libs.ktor.client.mock)
|
||||
androidTestImplementation(libs.ktor.jackson)
|
||||
androidTestImplementation(libs.rules)
|
||||
androidTestImplementation(libs.uiautomator)
|
||||
|
||||
testImplementation(libs.kotlin.inject.runtime)
|
||||
testImplementation(libs.junit.junit)
|
||||
}
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
-keep class org.isoron.** { *; }
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
-keep class android.support.test.** { *; }
|
||||
-keep class org.mockito.** { *; }
|
||||
-keep class org.junit.** { *; }
|
||||
-keep class kotlin.** { *; }
|
||||
|
||||
|
||||
@ -52,10 +52,8 @@ import java.util.concurrent.CountDownLatch
|
||||
|
||||
@MediumTest
|
||||
abstract class BaseAndroidTest : TestCase() {
|
||||
@JvmField
|
||||
protected var testContext: Context = InstrumentationRegistry.getInstrumentation().context
|
||||
|
||||
@JvmField
|
||||
protected var targetContext: Context =
|
||||
InstrumentationRegistry.getInstrumentation().targetContext
|
||||
protected lateinit var prefs: Preferences
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
package org.isoron.uhabits
|
||||
|
||||
import android.content.Context
|
||||
import dev.mokkery.mock
|
||||
import me.tatarka.inject.annotations.Component
|
||||
import me.tatarka.inject.annotations.Provides
|
||||
import org.isoron.uhabits.activities.HabitsDirFinder
|
||||
@ -37,7 +38,6 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsSelectionMenuBeh
|
||||
import org.isoron.uhabits.inject.ActivityContext
|
||||
import org.isoron.uhabits.inject.ActivityScope
|
||||
import org.isoron.uhabits.inject.HabitsApplicationComponent
|
||||
import org.mockito.kotlin.mock
|
||||
|
||||
@ActivityScope
|
||||
@Component
|
||||
|
||||
@ -20,15 +20,15 @@ package org.isoron.uhabits.activities.habits.list.views
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.MediumTest
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import dev.mokkery.verifyNoMoreCalls
|
||||
import org.isoron.uhabits.BaseViewTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@MediumTest
|
||||
@ -47,19 +47,19 @@ class HeaderViewTest : BaseViewTest() {
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testRender() {
|
||||
whenever(prefs.isCheckmarkSequenceReversed).thenReturn(false)
|
||||
every { prefs.isCheckmarkSequenceReversed } returns false
|
||||
assertRenders(view, PATH + "render.png")
|
||||
verify(prefs).isCheckmarkSequenceReversed
|
||||
verifyNoMoreInteractions(prefs)
|
||||
verify { prefs.isCheckmarkSequenceReversed }
|
||||
verifyNoMoreCalls(prefs)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testRender_reverse() {
|
||||
doReturn(true).whenever(prefs).isCheckmarkSequenceReversed
|
||||
every { prefs.isCheckmarkSequenceReversed } returns true
|
||||
assertRenders(view, PATH + "render_reverse.png")
|
||||
verify(prefs).isCheckmarkSequenceReversed
|
||||
verifyNoMoreInteractions(prefs)
|
||||
verify { prefs.isCheckmarkSequenceReversed }
|
||||
verifyNoMoreCalls(prefs)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@ -20,6 +20,9 @@ package org.isoron.uhabits.activities.habits.list.views
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.MediumTest
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.mock
|
||||
import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.isoron.uhabits.BaseViewTest
|
||||
@ -27,9 +30,6 @@ import org.isoron.uhabits.core.ui.screens.habits.list.HintList
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@MediumTest
|
||||
@ -44,8 +44,8 @@ class HintViewTest : BaseViewTest() {
|
||||
view = HintView(targetContext, list)
|
||||
measureView(view, 400f, 200f)
|
||||
val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
||||
doReturn(true).whenever(list).shouldShow()
|
||||
doReturn(text).whenever(list).pop()
|
||||
every { list.shouldShow() } returns true
|
||||
every { list.pop() } returns text
|
||||
view.showNext()
|
||||
skipAnimation(view)
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ import android.os.Parcelable.ClassLoaderCreator
|
||||
import androidx.customview.view.AbsSavedState
|
||||
|
||||
class BundleSavedState : AbsSavedState {
|
||||
@JvmField val bundle: Bundle?
|
||||
val bundle: Bundle?
|
||||
|
||||
constructor(superState: Parcelable?, bundle: Bundle?) : super(superState!!) {
|
||||
this.bundle = bundle
|
||||
|
||||
@ -28,11 +28,7 @@ import org.isoron.uhabits.core.test.HabitFixtures
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.junit.MockitoJUnitRunner
|
||||
import org.mockito.kotlin.spy
|
||||
|
||||
@RunWith(MockitoJUnitRunner::class)
|
||||
open class BaseAndroidJVMTest {
|
||||
private lateinit var habitList: HabitList
|
||||
protected lateinit var fixtures: HabitFixtures
|
||||
@ -44,7 +40,7 @@ open class BaseAndroidJVMTest {
|
||||
open fun setUp() {
|
||||
setToday(LocalDate(2015, 1, 25))
|
||||
modelFactory = MemoryModelFactory()
|
||||
habitList = spy(modelFactory.buildHabitList())
|
||||
habitList = modelFactory.buildHabitList()
|
||||
fixtures = HabitFixtures(modelFactory, habitList)
|
||||
taskRunner = SingleThreadTaskRunner()
|
||||
commandRunner = CommandRunner(taskRunner)
|
||||
|
||||
@ -18,16 +18,15 @@
|
||||
*/
|
||||
package org.isoron.uhabits.receivers
|
||||
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import dev.mokkery.verifyNoMoreCalls
|
||||
import org.isoron.platform.time.LocalDate
|
||||
import org.isoron.uhabits.BaseAndroidJVMTest
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.reminders.ReminderScheduler
|
||||
import org.isoron.uhabits.core.ui.NotificationTray
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
|
||||
class ReminderControllerTest : BaseAndroidJVMTest() {
|
||||
private lateinit var controller: ReminderController
|
||||
@ -49,25 +48,25 @@ class ReminderControllerTest : BaseAndroidJVMTest() {
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnDismiss() {
|
||||
verifyNoMoreInteractions(reminderScheduler)
|
||||
verifyNoMoreInteractions(notificationTray)
|
||||
verifyNoMoreInteractions(preferences)
|
||||
verifyNoMoreCalls(reminderScheduler)
|
||||
verifyNoMoreCalls(notificationTray)
|
||||
verifyNoMoreCalls(preferences)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnShowReminder() {
|
||||
val habit: Habit = mock()
|
||||
val habit = fixtures.createEmptyHabit()
|
||||
val date = LocalDate(2015, 1, 25)
|
||||
controller.onShowReminder(habit, date, 456)
|
||||
verify(notificationTray).show(habit, date, 456)
|
||||
verify(reminderScheduler).scheduleAll()
|
||||
verify { notificationTray.show(habit, date, 456) }
|
||||
verify { reminderScheduler.scheduleAll() }
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnBootCompleted() {
|
||||
controller.onBootCompleted()
|
||||
verify(reminderScheduler).scheduleAll()
|
||||
verify { reminderScheduler.scheduleAll() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
alias(libs.plugins.ktlint.plugin)
|
||||
alias(libs.plugins.mokkery)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
@ -61,13 +62,22 @@ kotlin {
|
||||
implementation(libs.sqlite.jdbc)
|
||||
implementation(libs.hamcrest)
|
||||
implementation(libs.commons.io)
|
||||
implementation(libs.mockito.kotlin)
|
||||
implementation(libs.junit.jupiter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mokkery {
|
||||
defaultMockMode.set(dev.mokkery.MockMode.autofill)
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-Xjvm-default=all")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<ProcessResources> {
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||
}
|
||||
|
||||
@ -43,15 +43,15 @@ open class CommandRunner(
|
||||
)
|
||||
}
|
||||
|
||||
fun addListener(l: Listener) {
|
||||
open fun addListener(l: Listener) {
|
||||
listeners.add(l)
|
||||
}
|
||||
|
||||
fun notifyListeners(command: Command) {
|
||||
open fun notifyListeners(command: Command) {
|
||||
for (l in listeners) l.onCommandFinished(command)
|
||||
}
|
||||
|
||||
fun removeListener(l: Listener) {
|
||||
open fun removeListener(l: Listener) {
|
||||
listeners.remove(l)
|
||||
}
|
||||
|
||||
|
||||
@ -34,16 +34,12 @@ data class Frequency(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val DAILY = Frequency(1, 1)
|
||||
|
||||
@JvmField
|
||||
val THREE_TIMES_PER_WEEK = Frequency(3, 7)
|
||||
|
||||
@JvmField
|
||||
val TWO_TIMES_PER_WEEK = Frequency(2, 7)
|
||||
|
||||
@JvmField
|
||||
val WEEKLY = Frequency(1, 7)
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,10 +25,10 @@ import org.isoron.platform.io.format
|
||||
* An ordered collection of [Habit]s.
|
||||
*/
|
||||
abstract class HabitList : Iterable<Habit> {
|
||||
val observable: ModelObservable
|
||||
open val observable: ModelObservable = ModelObservable()
|
||||
|
||||
@JvmField
|
||||
protected val filter: HabitMatcher
|
||||
open var filter: HabitMatcher = HabitMatcher(isArchivedAllowed = true)
|
||||
internal set
|
||||
|
||||
/**
|
||||
* Creates a new HabitList.
|
||||
@ -37,13 +37,9 @@ abstract class HabitList : Iterable<Habit> {
|
||||
* populated by some pre-existing habits, for example, from a certain
|
||||
* database.
|
||||
*/
|
||||
constructor() {
|
||||
observable = ModelObservable()
|
||||
filter = HabitMatcher(isArchivedAllowed = true)
|
||||
}
|
||||
constructor()
|
||||
|
||||
protected constructor(filter: HabitMatcher) {
|
||||
observable = ModelObservable()
|
||||
this.filter = filter
|
||||
}
|
||||
|
||||
@ -104,7 +100,7 @@ abstract class HabitList : Iterable<Habit> {
|
||||
* @return the index of the habit, or -1 if not in the list
|
||||
*/
|
||||
abstract fun indexOf(h: Habit): Int
|
||||
val isEmpty: Boolean
|
||||
open val isEmpty: Boolean
|
||||
get() = size() == 0
|
||||
|
||||
/**
|
||||
@ -159,7 +155,7 @@ abstract class HabitList : Iterable<Habit> {
|
||||
*
|
||||
* @param habit the habit that has been modified.
|
||||
*/
|
||||
fun update(habit: Habit) {
|
||||
open fun update(habit: Habit) {
|
||||
update(listOf(habit))
|
||||
}
|
||||
|
||||
@ -168,7 +164,7 @@ abstract class HabitList : Iterable<Habit> {
|
||||
* habit, containing the fields name, description, frequency numerator,
|
||||
* frequency denominator and color.
|
||||
*/
|
||||
fun writeCSV(): String {
|
||||
open fun writeCSV(): String {
|
||||
val sb = StringBuilder()
|
||||
val header = arrayOf(
|
||||
"Position",
|
||||
|
||||
@ -33,7 +33,6 @@ data class HabitMatcher(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val WITH_ALARM = HabitMatcher(
|
||||
isArchivedAllowed = true,
|
||||
isReminderRequired = true
|
||||
|
||||
@ -25,7 +25,7 @@ import org.isoron.uhabits.core.models.HabitMatcher
|
||||
/**
|
||||
* In-memory implementation of [HabitList].
|
||||
*/
|
||||
class MemoryHabitList : HabitList {
|
||||
open class MemoryHabitList : HabitList {
|
||||
private val list = mutableListOf<Habit>()
|
||||
|
||||
@get:Synchronized
|
||||
|
||||
@ -31,18 +31,18 @@ import kotlin.math.min
|
||||
open class Preferences(private val storage: Storage) {
|
||||
private val listeners: MutableList<Listener>
|
||||
private var shouldReverseCheckmarks: Boolean? = null
|
||||
fun addListener(listener: Listener) {
|
||||
open fun addListener(listener: Listener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
fun getDefaultHabitColor(fallbackColor: Int): Int {
|
||||
open fun getDefaultHabitColor(fallbackColor: Int): Int {
|
||||
return storage.getInt(
|
||||
"pref_default_habit_palette_color",
|
||||
fallbackColor
|
||||
)
|
||||
}
|
||||
|
||||
var defaultPrimaryOrder: HabitList.Order
|
||||
open var defaultPrimaryOrder: HabitList.Order
|
||||
get() {
|
||||
val name = storage.getString("pref_default_order", "BY_POSITION")
|
||||
return try {
|
||||
@ -55,7 +55,7 @@ open class Preferences(private val storage: Storage) {
|
||||
set(order) {
|
||||
storage.putString("pref_default_order", order.name)
|
||||
}
|
||||
var defaultSecondaryOrder: HabitList.Order
|
||||
open var defaultSecondaryOrder: HabitList.Order
|
||||
get() {
|
||||
val name = storage.getString("pref_default_secondary_order", "BY_NAME_ASC")
|
||||
return try {
|
||||
@ -68,22 +68,22 @@ open class Preferences(private val storage: Storage) {
|
||||
set(order) {
|
||||
storage.putString("pref_default_secondary_order", order.name)
|
||||
}
|
||||
var scoreCardSpinnerPosition: Int
|
||||
open var scoreCardSpinnerPosition: Int
|
||||
get() = min(4, max(0, storage.getInt("pref_score_view_interval", 1)))
|
||||
set(position) {
|
||||
storage.putInt("pref_score_view_interval", position)
|
||||
}
|
||||
var barCardBoolSpinnerPosition: Int
|
||||
open var barCardBoolSpinnerPosition: Int
|
||||
get() = min(3, max(0, storage.getInt("pref_bar_card_bool_spinner", 0)))
|
||||
set(position) {
|
||||
storage.putInt("pref_bar_card_bool_spinner", position)
|
||||
}
|
||||
var barCardNumericalSpinnerPosition: Int
|
||||
open var barCardNumericalSpinnerPosition: Int
|
||||
get() = min(4, max(0, storage.getInt("pref_bar_card_numerical_spinner", 0)))
|
||||
set(position) {
|
||||
storage.putInt("pref_bar_card_numerical_spinner", position)
|
||||
}
|
||||
val lastHintNumber: Int
|
||||
open val lastHintNumber: Int
|
||||
get() = storage.getInt("last_hint_number", -1)
|
||||
open val lastHintDate: LocalDate?
|
||||
get() {
|
||||
@ -91,74 +91,74 @@ open class Preferences(private val storage: Storage) {
|
||||
return if (unixTime < 0) null else LocalDate.fromUnixTime(unixTime)
|
||||
}
|
||||
|
||||
var showArchived: Boolean
|
||||
open var showArchived: Boolean
|
||||
get() = storage.getBoolean("pref_show_archived", false)
|
||||
set(showArchived) {
|
||||
storage.putBoolean("pref_show_archived", showArchived)
|
||||
}
|
||||
var showCompleted: Boolean
|
||||
open var showCompleted: Boolean
|
||||
get() = storage.getBoolean("pref_show_completed", true)
|
||||
set(showCompleted) {
|
||||
storage.putBoolean("pref_show_completed", showCompleted)
|
||||
}
|
||||
|
||||
var theme: Int
|
||||
open var theme: Int
|
||||
get() = storage.getInt("pref_theme", ThemeSwitcher.THEME_AUTOMATIC)
|
||||
set(theme) {
|
||||
storage.putInt("pref_theme", theme)
|
||||
}
|
||||
|
||||
fun incrementLaunchCount() {
|
||||
open fun incrementLaunchCount() {
|
||||
storage.putInt("launch_count", launchCount + 1)
|
||||
}
|
||||
|
||||
val launchCount: Int
|
||||
open val launchCount: Int
|
||||
get() = storage.getInt("launch_count", 0)
|
||||
var isDeveloper: Boolean
|
||||
open var isDeveloper: Boolean
|
||||
get() = storage.getBoolean("pref_developer", false)
|
||||
set(isDeveloper) {
|
||||
storage.putBoolean("pref_developer", isDeveloper)
|
||||
}
|
||||
var isFirstRun: Boolean
|
||||
open var isFirstRun: Boolean
|
||||
get() = storage.getBoolean("pref_first_run", true)
|
||||
set(isFirstRun) {
|
||||
storage.putBoolean("pref_first_run", isFirstRun)
|
||||
}
|
||||
var isPureBlackEnabled: Boolean
|
||||
open var isPureBlackEnabled: Boolean
|
||||
get() = storage.getBoolean("pref_pure_black", false)
|
||||
set(enabled) {
|
||||
storage.putBoolean("pref_pure_black", enabled)
|
||||
}
|
||||
var isShortToggleEnabled: Boolean
|
||||
open var isShortToggleEnabled: Boolean
|
||||
get() = storage.getBoolean("pref_short_toggle", false)
|
||||
set(enabled) {
|
||||
storage.putBoolean("pref_short_toggle", enabled)
|
||||
}
|
||||
|
||||
var isConfettiAnimationDisabled: Boolean
|
||||
open var isConfettiAnimationDisabled: Boolean
|
||||
get() = storage.getBoolean("pref_disable_animation", false)
|
||||
set(enabled) {
|
||||
storage.putBoolean("pref_disable_animation", enabled)
|
||||
}
|
||||
|
||||
fun removeListener(listener: Listener) {
|
||||
open fun removeListener(listener: Listener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
open fun clear() {
|
||||
storage.clear()
|
||||
}
|
||||
|
||||
fun setDefaultHabitColor(color: Int) {
|
||||
open fun setDefaultHabitColor(color: Int) {
|
||||
storage.putInt("pref_default_habit_palette_color", color)
|
||||
}
|
||||
|
||||
fun setNotificationsSticky(sticky: Boolean) {
|
||||
open fun setNotificationsSticky(sticky: Boolean) {
|
||||
storage.putBoolean("pref_sticky_notifications", sticky)
|
||||
for (l in listeners) l.onNotificationsChanged()
|
||||
}
|
||||
|
||||
fun shouldMakeNotificationsSticky(): Boolean {
|
||||
open fun shouldMakeNotificationsSticky(): Boolean {
|
||||
return storage.getBoolean("pref_sticky_notifications", false)
|
||||
}
|
||||
|
||||
@ -183,35 +183,35 @@ open class Preferences(private val storage: Storage) {
|
||||
for (l in listeners) l.onCheckmarkSequenceChanged()
|
||||
}
|
||||
|
||||
val midnightDelayHours: Int
|
||||
open val midnightDelayHours: Int
|
||||
get() = if (isMidnightDelayEnabled) MIDNIGHT_DELAY_HOURS else 0
|
||||
|
||||
companion object {
|
||||
const val MIDNIGHT_DELAY_HOURS = 3
|
||||
}
|
||||
|
||||
fun updateLastHint(number: Int, date: LocalDate) {
|
||||
open fun updateLastHint(number: Int, date: LocalDate) {
|
||||
storage.putInt("last_hint_number", number)
|
||||
storage.putLong("last_hint_timestamp", date.unixTime)
|
||||
}
|
||||
|
||||
var lastAppVersion: Int
|
||||
open var lastAppVersion: Int
|
||||
get() = storage.getInt("last_version", 0)
|
||||
set(version) {
|
||||
storage.putInt("last_version", version)
|
||||
}
|
||||
var widgetOpacity: Int
|
||||
open var widgetOpacity: Int
|
||||
get() = storage.getString("pref_widget_opacity", "255").toInt()
|
||||
set(value) {
|
||||
storage.putString("pref_widget_opacity", value.toString())
|
||||
}
|
||||
var isSkipEnabled: Boolean
|
||||
open var isSkipEnabled: Boolean
|
||||
get() = storage.getBoolean("pref_skip_enabled", false)
|
||||
set(value) {
|
||||
storage.putBoolean("pref_skip_enabled", value)
|
||||
}
|
||||
|
||||
var areQuestionMarksEnabled: Boolean
|
||||
open var areQuestionMarksEnabled: Boolean
|
||||
get() = storage.getBoolean("pref_unknown_enabled", false)
|
||||
set(value) {
|
||||
storage.putBoolean("pref_unknown_enabled", value)
|
||||
@ -225,12 +225,12 @@ open class Preferences(private val storage: Storage) {
|
||||
* unless the user changed this in the settings.
|
||||
*/
|
||||
@get:Deprecated("")
|
||||
val firstWeekdayInt: Int
|
||||
open val firstWeekdayInt: Int
|
||||
get() {
|
||||
val weekday = storage.getString("pref_first_weekday", "")
|
||||
return if (weekday.isEmpty()) getFirstWeekdayNumberAccordingToLocale() else weekday.toInt()
|
||||
}
|
||||
val firstWeekday: DayOfWeek
|
||||
open val firstWeekday: DayOfWeek
|
||||
get() {
|
||||
var weekday = storage.getString("pref_first_weekday", "-1").toInt()
|
||||
if (weekday < 0) weekday = getFirstWeekdayNumberAccordingToLocale()
|
||||
@ -258,7 +258,7 @@ open class Preferences(private val storage: Storage) {
|
||||
fun getInt(key: String, defValue: Int): Int
|
||||
fun getLong(key: String, defValue: Long): Long
|
||||
fun getString(key: String, defValue: String): String
|
||||
fun onAttached(preferences: Preferences)
|
||||
fun onAttached(preferences: Preferences) {}
|
||||
fun putBoolean(key: String, value: Boolean)
|
||||
fun putInt(key: String, value: Int)
|
||||
fun putLong(key: String, value: Long)
|
||||
|
||||
@ -24,12 +24,12 @@ import org.isoron.uhabits.core.AppScope
|
||||
|
||||
@AppScope
|
||||
@Inject
|
||||
class WidgetPreferences(private val storage: Preferences.Storage) {
|
||||
fun addWidget(widgetId: Int, habitIds: LongArray) {
|
||||
open class WidgetPreferences(private val storage: Preferences.Storage) {
|
||||
open fun addWidget(widgetId: Int, habitIds: LongArray) {
|
||||
storage.putLongArray(getHabitIdKey(widgetId), habitIds)
|
||||
}
|
||||
|
||||
fun getHabitIdsFromWidgetId(widgetId: Int): LongArray {
|
||||
open fun getHabitIdsFromWidgetId(widgetId: Int): LongArray {
|
||||
val habitIdKey = getHabitIdKey(widgetId)
|
||||
return try {
|
||||
storage.getLongArray(habitIdKey, longArrayOf())
|
||||
@ -43,12 +43,12 @@ class WidgetPreferences(private val storage: Preferences.Storage) {
|
||||
}
|
||||
}
|
||||
|
||||
fun removeWidget(id: Int) {
|
||||
open fun removeWidget(id: Int) {
|
||||
val habitIdKey = getHabitIdKey(id)
|
||||
storage.remove(habitIdKey)
|
||||
}
|
||||
|
||||
fun getSnoozeTime(id: Long): Long {
|
||||
open fun getSnoozeTime(id: Long): Long {
|
||||
return storage.getLong(getSnoozeKey(id), 0)
|
||||
}
|
||||
|
||||
@ -60,11 +60,11 @@ class WidgetPreferences(private val storage: Preferences.Storage) {
|
||||
return format("snooze-%06d", id.toInt())
|
||||
}
|
||||
|
||||
fun removeSnoozeTime(id: Long) {
|
||||
open fun removeSnoozeTime(id: Long) {
|
||||
storage.putLong(getSnoozeKey(id), 0)
|
||||
}
|
||||
|
||||
fun setSnoozeTime(id: Long, time: Long) {
|
||||
open fun setSnoozeTime(id: Long, time: Long) {
|
||||
storage.putLong(getSnoozeKey(id), time)
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,14 +33,14 @@ import org.isoron.uhabits.core.tasks.TaskRunner
|
||||
|
||||
@AppScope
|
||||
@Inject
|
||||
class NotificationTray(
|
||||
open class NotificationTray(
|
||||
private val taskRunner: TaskRunner,
|
||||
private val commandRunner: CommandRunner,
|
||||
private val preferences: Preferences,
|
||||
private val systemTray: SystemTray
|
||||
) : CommandRunner.Listener, Preferences.Listener {
|
||||
private val active: MutableMap<Habit, NotificationData> = mutableMapOf()
|
||||
fun cancel(habit: Habit) {
|
||||
open fun cancel(habit: Habit) {
|
||||
val notificationId = getNotificationId(habit)
|
||||
systemTray.removeNotification(notificationId)
|
||||
active.remove(habit)
|
||||
@ -61,18 +61,18 @@ class NotificationTray(
|
||||
reshowAll()
|
||||
}
|
||||
|
||||
fun show(habit: Habit, date: LocalDate, reminderTime: Long) {
|
||||
open fun show(habit: Habit, date: LocalDate, reminderTime: Long) {
|
||||
val data = NotificationData(date, reminderTime)
|
||||
active[habit] = data
|
||||
taskRunner.execute(ShowNotificationTask(habit, data))
|
||||
}
|
||||
|
||||
fun startListening() {
|
||||
open fun startListening() {
|
||||
commandRunner.addListener(this)
|
||||
preferences.addListener(this)
|
||||
}
|
||||
|
||||
fun stopListening() {
|
||||
open fun stopListening() {
|
||||
commandRunner.removeListener(this)
|
||||
preferences.removeListener(this)
|
||||
}
|
||||
@ -88,7 +88,7 @@ class NotificationTray(
|
||||
}
|
||||
}
|
||||
|
||||
fun reshow(habit: Habit) {
|
||||
open fun reshow(habit: Habit) {
|
||||
active[habit]?.let {
|
||||
taskRunner.execute(ShowNotificationTask(habit, it))
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
|
||||
abstract class ThemeSwitcher(private val preferences: Preferences) {
|
||||
fun apply() {
|
||||
open fun apply() {
|
||||
if (isNightMode) {
|
||||
if (preferences.isPureBlackEnabled) applyPureBlackTheme() else applyDarkTheme()
|
||||
} else {
|
||||
@ -35,7 +35,7 @@ abstract class ThemeSwitcher(private val preferences: Preferences) {
|
||||
abstract fun applyPureBlackTheme()
|
||||
abstract fun getSystemTheme(): Int
|
||||
abstract val currentTheme: Theme?
|
||||
val isNightMode: Boolean
|
||||
open val isNightMode: Boolean
|
||||
get() {
|
||||
val systemTheme = getSystemTheme()
|
||||
val userTheme = preferences.theme
|
||||
@ -43,7 +43,7 @@ abstract class ThemeSwitcher(private val preferences: Preferences) {
|
||||
systemTheme == THEME_DARK && userTheme == THEME_AUTOMATIC
|
||||
}
|
||||
|
||||
fun toggleNightMode() {
|
||||
open fun toggleNightMode() {
|
||||
val systemTheme = getSystemTheme()
|
||||
val userTheme = preferences.theme
|
||||
if (userTheme == THEME_AUTOMATIC) {
|
||||
|
||||
@ -48,11 +48,11 @@ open class ListHabitsBehavior(
|
||||
private val prefs: Preferences,
|
||||
private val bugReporter: BugReporter
|
||||
) {
|
||||
fun onClickHabit(h: Habit) {
|
||||
open fun onClickHabit(h: Habit) {
|
||||
screen.showHabitScreen(h)
|
||||
}
|
||||
|
||||
fun onEdit(habit: Habit, date: LocalDate, x: Float, y: Float) {
|
||||
open fun onEdit(habit: Habit, date: LocalDate, x: Float, y: Float) {
|
||||
val entry = habit.computedEntries.get(date)
|
||||
if (habit.type == HabitType.NUMERICAL) {
|
||||
val oldValue = entry.value.toDouble() / 1000
|
||||
@ -80,7 +80,7 @@ open class ListHabitsBehavior(
|
||||
}
|
||||
}
|
||||
|
||||
fun onExportCSV() {
|
||||
open fun onExportCSV() {
|
||||
val selected = habitList.toList()
|
||||
val outputDir = dirFinder.getCSVOutputDir()
|
||||
taskRunner.execute(
|
||||
@ -96,24 +96,24 @@ open class ListHabitsBehavior(
|
||||
)
|
||||
}
|
||||
|
||||
fun onFirstRun() {
|
||||
open fun onFirstRun() {
|
||||
prefs.isFirstRun = false
|
||||
prefs.updateLastHint(-1, getToday())
|
||||
screen.showIntroScreen()
|
||||
}
|
||||
|
||||
fun onReorderHabit(from: Habit, to: Habit) {
|
||||
open fun onReorderHabit(from: Habit, to: Habit) {
|
||||
taskRunner.execute { habitList.reorder(from, to) }
|
||||
}
|
||||
|
||||
fun onRepairDB() {
|
||||
open fun onRepairDB() {
|
||||
taskRunner.execute {
|
||||
habitList.repair()
|
||||
screen.showMessage(Message.DATABASE_REPAIRED)
|
||||
}
|
||||
}
|
||||
|
||||
fun onSendBugReport() {
|
||||
open fun onSendBugReport() {
|
||||
bugReporter.dumpBugReportToFile()
|
||||
try {
|
||||
val log = bugReporter.getBugReport()
|
||||
@ -124,12 +124,12 @@ open class ListHabitsBehavior(
|
||||
}
|
||||
}
|
||||
|
||||
fun onStartup() {
|
||||
open fun onStartup() {
|
||||
prefs.incrementLaunchCount()
|
||||
if (prefs.isFirstRun) onFirstRun()
|
||||
}
|
||||
|
||||
fun onToggle(habit: Habit, date: LocalDate, value: Int, notes: String, x: Float, y: Float) {
|
||||
open fun onToggle(habit: Habit, date: LocalDate, value: Int, notes: String, x: Float, y: Float) {
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(habitList, habit, date, value, notes)
|
||||
)
|
||||
|
||||
@ -32,7 +32,7 @@ import org.isoron.uhabits.core.preferences.WidgetPreferences
|
||||
|
||||
@AppScope
|
||||
@Inject
|
||||
class ReminderScheduler(
|
||||
open class ReminderScheduler(
|
||||
private val commandRunner: CommandRunner,
|
||||
private val habitList: HabitList,
|
||||
private val sys: SystemScheduler,
|
||||
@ -46,7 +46,7 @@ class ReminderScheduler(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun schedule(habit: Habit) {
|
||||
open fun schedule(habit: Habit) {
|
||||
if (habit.id == null) {
|
||||
sys.log("ReminderScheduler", "Habit has null id. Returning.")
|
||||
return
|
||||
@ -75,7 +75,7 @@ class ReminderScheduler(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun scheduleAtTime(habit: Habit, reminderTime: Long) {
|
||||
open fun scheduleAtTime(habit: Habit, reminderTime: Long) {
|
||||
sys.log("ReminderScheduler", "Scheduling alarm for habit=" + habit.id)
|
||||
if (!habit.hasReminder()) {
|
||||
sys.log("ReminderScheduler", "habit=" + habit.id + " has no reminder. Skipping.")
|
||||
@ -91,29 +91,29 @@ class ReminderScheduler(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun scheduleAll() {
|
||||
open fun scheduleAll() {
|
||||
sys.log("ReminderScheduler", "Scheduling all alarms")
|
||||
val reminderHabits = habitList.getFiltered(HabitMatcher.WITH_ALARM)
|
||||
for (habit in reminderHabits) schedule(habit)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun hasHabitsWithReminders(): Boolean {
|
||||
open fun hasHabitsWithReminders(): Boolean {
|
||||
return !habitList.getFiltered(HabitMatcher.WITH_ALARM).isEmpty
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun startListening() {
|
||||
open fun startListening() {
|
||||
commandRunner.addListener(this)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun stopListening() {
|
||||
open fun stopListening() {
|
||||
commandRunner.removeListener(this)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun snoozeReminder(habit: Habit, minutes: Long) {
|
||||
open fun snoozeReminder(habit: Habit, minutes: Long) {
|
||||
val now = DateUtils.applyTimezone(DateUtils.getLocalTime())
|
||||
val snoozedUntil = now + minutes * 60 * 1000
|
||||
widgetPreferences.setSnoozeTime(habit.id!!, snoozedUntil)
|
||||
|
||||
@ -44,18 +44,18 @@ open class MidnightTimer(
|
||||
private val logger = logging.getLogger("MidnightTimer")
|
||||
|
||||
@Synchronized
|
||||
fun addListener(listener: MidnightListener) {
|
||||
open fun addListener(listener: MidnightListener) {
|
||||
this.listeners.add(listener)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun onPause(): MutableList<Runnable>? {
|
||||
open fun onPause(): MutableList<Runnable>? {
|
||||
logger.info("Pausing timer")
|
||||
return executor.shutdownNow()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun onResume(
|
||||
open fun onResume(
|
||||
delayOffsetInMillis: Long = DateUtils.SECOND_LENGTH,
|
||||
testExecutor: ScheduledExecutorService? = null
|
||||
) {
|
||||
@ -71,7 +71,7 @@ open class MidnightTimer(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun removeListener(listener: MidnightListener) = this.listeners.remove(listener)
|
||||
open fun removeListener(listener: MidnightListener) = this.listeners.remove(listener)
|
||||
|
||||
@Synchronized
|
||||
private fun notifyListeners() {
|
||||
|
||||
@ -18,17 +18,13 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core
|
||||
|
||||
import dev.mokkery.spy
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.isoron.platform.io.JavaDatabaseOpener
|
||||
import org.isoron.uhabits.core.models.memory.MemoryModelFactory
|
||||
import org.isoron.uhabits.core.test.HabitFixtures
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.junit.MockitoJUnitRunner
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.validateMockitoUsage
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
@ -38,7 +34,6 @@ import java.nio.file.Paths
|
||||
import java.util.GregorianCalendar
|
||||
import java.util.TimeZone
|
||||
|
||||
@RunWith(MockitoJUnitRunner::class)
|
||||
open class JvmBaseUnitTest : BaseUnitTest() {
|
||||
protected var databaseOpener: org.isoron.platform.io.DatabaseOpener = JavaDatabaseOpener()
|
||||
|
||||
@ -49,12 +44,6 @@ open class JvmBaseUnitTest : BaseUnitTest() {
|
||||
fixtures = HabitFixtures(modelFactory as MemoryModelFactory, habitList)
|
||||
}
|
||||
|
||||
@After
|
||||
@Throws(Exception::class)
|
||||
open fun tearDown() {
|
||||
validateMockitoUsage()
|
||||
}
|
||||
|
||||
fun unixTime(year: Int, month: Int, day: Int): Long {
|
||||
return unixTime(year, month, day, 0, 0)
|
||||
}
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.models.sqlite
|
||||
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
||||
@ -29,10 +31,9 @@ import org.isoron.uhabits.core.models.ModelObservable
|
||||
import org.isoron.uhabits.core.models.Reminder
|
||||
import org.isoron.uhabits.core.models.WeekdayList
|
||||
import org.isoron.uhabits.core.test.HabitFixtures
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import java.util.ArrayList
|
||||
import kotlin.test.assertNull
|
||||
|
||||
@ -74,17 +75,16 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
||||
habitList.observable.addListener(listener)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun tearDown() {
|
||||
@After
|
||||
fun tearDown() {
|
||||
habitList.observable.removeListener(listener)
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAdd_withDuplicate() {
|
||||
val habit = modelFactory.buildHabit()
|
||||
habitList.add(habit)
|
||||
verify(listener).onModelChange()
|
||||
verify { listener.onModelChange() }
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
habitList.add(habit)
|
||||
}
|
||||
|
||||
@ -18,6 +18,11 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.reminders
|
||||
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.matcher.any
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import org.isoron.platform.time.DateUtils
|
||||
import org.isoron.platform.time.DateUtils.removeTimezone
|
||||
import org.isoron.platform.time.DateUtils.setFixedLocalTime
|
||||
@ -30,16 +35,8 @@ import org.isoron.uhabits.core.preferences.WidgetPreferences
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.anyLong
|
||||
import org.mockito.junit.MockitoJUnitRunner
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
import java.util.TimeZone
|
||||
|
||||
@RunWith(MockitoJUnitRunner::class)
|
||||
class ReminderSchedulerTest : JvmBaseUnitTest() {
|
||||
private val habitId = 10L
|
||||
private lateinit var habit: Habit
|
||||
@ -60,8 +57,7 @@ class ReminderSchedulerTest : JvmBaseUnitTest() {
|
||||
}
|
||||
|
||||
@After
|
||||
override fun tearDown() {
|
||||
super.tearDown()
|
||||
fun tearDown() {
|
||||
setFixedLocalTime(null)
|
||||
setFixedTimeZone(null)
|
||||
}
|
||||
@ -80,16 +76,20 @@ class ReminderSchedulerTest : JvmBaseUnitTest() {
|
||||
habitList.add(h2)
|
||||
habitList.add(h3)
|
||||
reminderScheduler.scheduleAll()
|
||||
verify(sys).scheduleShowReminder(
|
||||
eq(unixTime(2015, 1, 27, 12, 30)),
|
||||
eq(h1),
|
||||
anyLong()
|
||||
)
|
||||
verify(sys).scheduleShowReminder(
|
||||
eq(unixTime(2015, 1, 26, 22, 30)),
|
||||
eq(h2),
|
||||
anyLong()
|
||||
)
|
||||
verify {
|
||||
sys.scheduleShowReminder(
|
||||
unixTime(2015, 1, 27, 12, 30),
|
||||
h1,
|
||||
any()
|
||||
)
|
||||
}
|
||||
verify {
|
||||
sys.scheduleShowReminder(
|
||||
unixTime(2015, 1, 26, 22, 30),
|
||||
h2,
|
||||
any()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -110,13 +110,14 @@ class ReminderSchedulerTest : JvmBaseUnitTest() {
|
||||
val todayCheckmarkTime = unixTime(2015, 1, 1, 0, 0)
|
||||
val tomorrowCheckmarkTime = unixTime(2015, 1, 2, 0, 0)
|
||||
habit.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY)
|
||||
whenever(widgetPreferences.getSnoozeTime(habitId)).thenReturn(snoozeTimeInFuture)
|
||||
every { widgetPreferences.getSnoozeTime(habitId) } returns snoozeTimeInFuture
|
||||
reminderScheduler.schedule(habit)
|
||||
verify(sys).scheduleShowReminder(snoozeTimeInFuture, habit, todayCheckmarkTime)
|
||||
whenever(widgetPreferences.getSnoozeTime(habitId)).thenReturn(snoozeTimeInPast)
|
||||
verify { sys.scheduleShowReminder(snoozeTimeInFuture, habit, todayCheckmarkTime) }
|
||||
every { widgetPreferences.getSnoozeTime(habitId) } returns snoozeTimeInPast
|
||||
reminderScheduler.schedule(habit)
|
||||
verify(sys)
|
||||
.scheduleShowReminder(regularReminderTime, habit, tomorrowCheckmarkTime)
|
||||
verify {
|
||||
sys.scheduleShowReminder(regularReminderTime, habit, tomorrowCheckmarkTime)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -164,10 +165,12 @@ class ReminderSchedulerTest : JvmBaseUnitTest() {
|
||||
atTime
|
||||
)
|
||||
}
|
||||
verify(sys).scheduleShowReminder(
|
||||
expectedReminderTime,
|
||||
habit,
|
||||
expectedCheckmarkTime
|
||||
)
|
||||
verify {
|
||||
sys.scheduleShowReminder(
|
||||
expectedReminderTime,
|
||||
habit,
|
||||
expectedCheckmarkTime
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,12 +18,13 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.tasks
|
||||
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import dev.mokkery.verify.VerifyMode.Companion.order
|
||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.kotlin.inOrder
|
||||
import org.mockito.kotlin.mock
|
||||
|
||||
@RunWith(JUnit4::class)
|
||||
class SingleThreadTaskRunnerTest : JvmBaseUnitTest() {
|
||||
@ -39,10 +40,11 @@ class SingleThreadTaskRunnerTest : JvmBaseUnitTest() {
|
||||
@Test
|
||||
fun test() {
|
||||
runner.execute(task)
|
||||
val inOrder = inOrder(task)
|
||||
inOrder.verify(task).onAttached(runner)
|
||||
inOrder.verify(task).onPreExecute()
|
||||
inOrder.verify(task).doInBackground()
|
||||
inOrder.verify(task).onPostExecute()
|
||||
verify(order) {
|
||||
task.onAttached(runner)
|
||||
task.onPreExecute()
|
||||
task.doInBackground()
|
||||
task.onPostExecute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,10 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.screens.habits.list
|
||||
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.resetCalls
|
||||
import dev.mokkery.verify
|
||||
import dev.mokkery.verifyNoMoreCalls
|
||||
import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.isoron.platform.time.LocalDate
|
||||
@ -26,10 +30,6 @@ import org.isoron.uhabits.core.commands.CreateRepetitionCommand
|
||||
import org.isoron.uhabits.core.commands.DeleteHabitsCommand
|
||||
import org.isoron.uhabits.core.models.Entry
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.reset
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
|
||||
class HabitCardListCacheTest : JvmBaseUnitTest() {
|
||||
private lateinit var cache: HabitCardListCache
|
||||
@ -51,7 +51,7 @@ class HabitCardListCacheTest : JvmBaseUnitTest() {
|
||||
cache.setListener(listener)
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
fun tearDown() {
|
||||
cache.onDetached()
|
||||
}
|
||||
|
||||
@ -62,8 +62,8 @@ class HabitCardListCacheTest : JvmBaseUnitTest() {
|
||||
commandRunner.run(
|
||||
DeleteHabitsCommand(habitList, listOf(h))
|
||||
)
|
||||
verify(listener).onItemRemoved(0)
|
||||
verify(listener).onRefreshFinished()
|
||||
verify { listener.onItemRemoved(0) }
|
||||
verify { listener.onRefreshFinished() }
|
||||
assertThat(cache.habitCount, equalTo(9))
|
||||
}
|
||||
|
||||
@ -71,9 +71,9 @@ class HabitCardListCacheTest : JvmBaseUnitTest() {
|
||||
fun testCommandListener_single() {
|
||||
val h2 = habitList.getByPosition(2)
|
||||
commandRunner.run(CreateRepetitionCommand(habitList, h2, today, Entry.NO, ""))
|
||||
verify(listener).onItemChanged(2)
|
||||
verify(listener).onRefreshFinished()
|
||||
verifyNoMoreInteractions(listener)
|
||||
verify { listener.onItemChanged(2) }
|
||||
verify { listener.onRefreshFinished() }
|
||||
verifyNoMoreCalls(listener)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -97,17 +97,17 @@ class HabitCardListCacheTest : JvmBaseUnitTest() {
|
||||
removeHabitAt(0)
|
||||
removeHabitAt(3)
|
||||
cache.refreshAllHabits()
|
||||
verify(listener).onItemRemoved(0)
|
||||
verify(listener).onItemRemoved(3)
|
||||
verify(listener).onRefreshFinished()
|
||||
verify { listener.onItemRemoved(0) }
|
||||
verify { listener.onItemRemoved(3) }
|
||||
verify { listener.onRefreshFinished() }
|
||||
assertThat(cache.habitCount, equalTo(8))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRefreshWithNoChanges() {
|
||||
cache.refreshAllHabits()
|
||||
verify(listener).onRefreshFinished()
|
||||
verifyNoMoreInteractions(listener)
|
||||
verify { listener.onRefreshFinished() }
|
||||
verifyNoMoreCalls(listener)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -119,8 +119,8 @@ class HabitCardListCacheTest : JvmBaseUnitTest() {
|
||||
assertThat(cache.getHabitByPosition(2), equalTo(h3))
|
||||
assertThat(cache.getHabitByPosition(7), equalTo(h2))
|
||||
assertThat(cache.getHabitByPosition(6), equalTo(h7))
|
||||
verify(listener).onItemMoved(2, 7)
|
||||
verifyNoMoreInteractions(listener)
|
||||
verify { listener.onItemMoved(2, 7) }
|
||||
verifyNoMoreCalls(listener)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -130,19 +130,19 @@ class HabitCardListCacheTest : JvmBaseUnitTest() {
|
||||
val h7 = habitList.getByPosition(7)
|
||||
assertThat(cache.getHabitByPosition(2), equalTo(h2))
|
||||
assertThat(cache.getHabitByPosition(7), equalTo(h7))
|
||||
reset(listener)
|
||||
resetCalls(listener)
|
||||
habitList.reorder(h2, h7)
|
||||
cache.refreshAllHabits()
|
||||
assertThat(cache.getHabitByPosition(2), equalTo(h3))
|
||||
assertThat(cache.getHabitByPosition(7), equalTo(h2))
|
||||
assertThat(cache.getHabitByPosition(6), equalTo(h7))
|
||||
verify(listener).onItemMoved(3, 2)
|
||||
verify(listener).onItemMoved(4, 3)
|
||||
verify(listener).onItemMoved(5, 4)
|
||||
verify(listener).onItemMoved(6, 5)
|
||||
verify(listener).onItemMoved(7, 6)
|
||||
verify(listener).onRefreshFinished()
|
||||
verifyNoMoreInteractions(listener)
|
||||
verify { listener.onItemMoved(3, 2) }
|
||||
verify { listener.onItemMoved(4, 3) }
|
||||
verify { listener.onItemMoved(5, 4) }
|
||||
verify { listener.onItemMoved(6, 5) }
|
||||
verify { listener.onItemMoved(7, 6) }
|
||||
verify { listener.onRefreshFinished() }
|
||||
verifyNoMoreCalls(listener)
|
||||
}
|
||||
|
||||
private fun removeHabitAt(position: Int) {
|
||||
|
||||
@ -18,6 +18,10 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.screens.habits.list
|
||||
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.Matchers.equalTo
|
||||
import org.isoron.platform.time.LocalDate
|
||||
@ -25,9 +29,6 @@ import org.isoron.platform.time.getToday
|
||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
||||
import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
@ -52,19 +53,19 @@ class HintListTest : JvmBaseUnitTest() {
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun pop() {
|
||||
whenever(prefs.lastHintNumber).thenReturn(-1)
|
||||
every { prefs.lastHintNumber } returns -1
|
||||
assertThat(hintList.pop(), equalTo("hint1"))
|
||||
verify(prefs).updateLastHint(0, today)
|
||||
whenever(prefs.lastHintNumber).thenReturn(2)
|
||||
verify { prefs.updateLastHint(0, today) }
|
||||
every { prefs.lastHintNumber } returns 2
|
||||
assertNull(hintList.pop())
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun shouldShow() {
|
||||
whenever(prefs.lastHintDate).thenReturn(today)
|
||||
every { prefs.lastHintDate } returns today
|
||||
assertFalse(hintList.shouldShow())
|
||||
whenever(prefs.lastHintDate).thenReturn(yesterday)
|
||||
every { prefs.lastHintDate } returns yesterday
|
||||
assertTrue(hintList.shouldShow())
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,14 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.screens.habits.list
|
||||
|
||||
import dev.mokkery.answering.calls
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.answering.throws
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.matcher.any
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.resetCalls
|
||||
import dev.mokkery.verify
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.core.IsEqual.equalTo
|
||||
@ -30,14 +38,6 @@ import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.ui.callbacks.NumberPickerCallback
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.KArgumentCaptor
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.clearInvocations
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
import java.nio.file.Files
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
@ -52,7 +52,7 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
||||
private lateinit var habit1: Habit
|
||||
private lateinit var habit2: Habit
|
||||
|
||||
var picker: KArgumentCaptor<NumberPickerCallback> = argumentCaptor()
|
||||
private var capturedPicker: NumberPickerCallback? = null
|
||||
|
||||
private val bugReporter: ListHabitsBehavior.BugReporter = mock()
|
||||
|
||||
@ -64,7 +64,7 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
||||
habit2 = fixtures.createNumericalHabit()
|
||||
habitList.add(habit1)
|
||||
habitList.add(habit2)
|
||||
clearInvocations(habitList)
|
||||
resetCalls(habitList)
|
||||
behavior = ListHabitsBehavior(
|
||||
habitList,
|
||||
dirFinder,
|
||||
@ -79,13 +79,17 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
||||
@Test
|
||||
fun testOnEdit() {
|
||||
val today = getToday()
|
||||
every {
|
||||
screen.showNumberPopup(any(), any(), any())
|
||||
} calls { args ->
|
||||
capturedPicker = args.arg<NumberPickerCallback>(2)
|
||||
Unit
|
||||
}
|
||||
behavior.onEdit(habit2, today, 0f, 0f)
|
||||
verify(screen).showNumberPopup(
|
||||
eq(0.1),
|
||||
eq(""),
|
||||
picker.capture()
|
||||
)
|
||||
picker.lastValue.onNumberPicked(100.0, "")
|
||||
verify {
|
||||
screen.showNumberPopup(0.1, "", any())
|
||||
}
|
||||
capturedPicker!!.onNumberPicked(100.0, "")
|
||||
assertThat(habit2.computedEntries.get(today).value, equalTo(100000))
|
||||
}
|
||||
|
||||
@ -93,9 +97,9 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
||||
@Throws(Exception::class)
|
||||
fun testOnExportCSV() {
|
||||
val outputDir = Files.createTempDirectory("CSV").toFile()
|
||||
whenever(dirFinder.getCSVOutputDir()).thenReturn(JavaUserFile(outputDir.toPath()))
|
||||
every { dirFinder.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath())
|
||||
behavior.onExportCSV()
|
||||
verify(screen).showSendFileScreen(any())
|
||||
verify { screen.showSendFileScreen(any()) }
|
||||
assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1))
|
||||
FileUtils.deleteDirectory(outputDir)
|
||||
}
|
||||
@ -105,16 +109,16 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
||||
fun testOnExportCSV_fail() {
|
||||
val outputDir = Files.createTempDirectory("CSV").toFile()
|
||||
outputDir.setWritable(false)
|
||||
whenever(dirFinder.getCSVOutputDir()).thenReturn(JavaUserFile(outputDir.toPath()))
|
||||
every { dirFinder.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath())
|
||||
behavior.onExportCSV()
|
||||
verify(screen).showMessage(ListHabitsBehavior.Message.COULD_NOT_EXPORT)
|
||||
verify { screen.showMessage(ListHabitsBehavior.Message.COULD_NOT_EXPORT) }
|
||||
assertTrue(outputDir.delete())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnHabitClick() {
|
||||
behavior.onClickHabit(habit1)
|
||||
verify(screen).showHabitScreen(habit1)
|
||||
verify { screen.showHabitScreen(habit1) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -122,42 +126,42 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
||||
val from = habit1
|
||||
val to = habit2
|
||||
behavior.onReorderHabit(from, to)
|
||||
verify(habitList).reorder(from, to)
|
||||
verify { habitList.reorder(from, to) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnRepairDB() {
|
||||
behavior.onRepairDB()
|
||||
verify(habitList).repair()
|
||||
verify(screen).showMessage(ListHabitsBehavior.Message.DATABASE_REPAIRED)
|
||||
verify { habitList.repair() }
|
||||
verify { screen.showMessage(ListHabitsBehavior.Message.DATABASE_REPAIRED) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSendBugReport() {
|
||||
whenever(bugReporter.getBugReport()).thenReturn("hello")
|
||||
every { bugReporter.getBugReport() } returns "hello"
|
||||
behavior.onSendBugReport()
|
||||
verify(bugReporter).dumpBugReportToFile()
|
||||
verify(screen).showSendBugReportToDeveloperScreen("hello")
|
||||
whenever(bugReporter.getBugReport()).thenThrow(RuntimeException())
|
||||
verify { bugReporter.dumpBugReportToFile() }
|
||||
verify { screen.showSendBugReportToDeveloperScreen("hello") }
|
||||
every { bugReporter.getBugReport() } throws RuntimeException()
|
||||
behavior.onSendBugReport()
|
||||
verify(screen).showMessage(ListHabitsBehavior.Message.COULD_NOT_GENERATE_BUG_REPORT)
|
||||
verify { screen.showMessage(ListHabitsBehavior.Message.COULD_NOT_GENERATE_BUG_REPORT) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartup_firstLaunch() {
|
||||
val today = getToday()
|
||||
whenever(prefs.isFirstRun).thenReturn(true)
|
||||
every { prefs.isFirstRun } returns true
|
||||
behavior.onStartup()
|
||||
verify(prefs).isFirstRun = false
|
||||
verify(prefs).updateLastHint(-1, today)
|
||||
verify(screen).showIntroScreen()
|
||||
verify { prefs.isFirstRun = false }
|
||||
verify { prefs.updateLastHint(-1, today) }
|
||||
verify { screen.showIntroScreen() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartup_notFirstLaunch() {
|
||||
whenever(prefs.isFirstRun).thenReturn(false)
|
||||
every { prefs.isFirstRun } returns false
|
||||
behavior.onStartup()
|
||||
verify(prefs).incrementLaunchCount()
|
||||
verify { prefs.incrementLaunchCount() }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -18,25 +18,20 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.screens.habits.list
|
||||
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.Matchers.equalTo
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.matcher.any
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.resetCalls
|
||||
import dev.mokkery.verify
|
||||
import dev.mokkery.verifyNoMoreCalls
|
||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
||||
import org.isoron.uhabits.core.models.HabitList
|
||||
import org.isoron.uhabits.core.models.HabitMatcher
|
||||
import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.ui.ThemeSwitcher
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.KArgumentCaptor
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.clearInvocations
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.never
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
import org.mockito.kotlin.whenever
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import dev.mokkery.verify.VerifyMode.Companion.not as notCalled
|
||||
|
||||
class ListHabitsMenuBehaviorTest : JvmBaseUnitTest() {
|
||||
private lateinit var behavior: ListHabitsMenuBehavior
|
||||
@ -49,131 +44,124 @@ class ListHabitsMenuBehaviorTest : JvmBaseUnitTest() {
|
||||
|
||||
private val themeSwitcher: ThemeSwitcher = mock()
|
||||
|
||||
private val matcherCaptor: KArgumentCaptor<HabitMatcher> = argumentCaptor()
|
||||
|
||||
private val orderCaptor: KArgumentCaptor<HabitList.Order> = argumentCaptor()
|
||||
|
||||
private val secondaryOrderCaptor: KArgumentCaptor<HabitList.Order> = argumentCaptor()
|
||||
private var capturedMatcher: HabitMatcher? = null
|
||||
private var capturedOrder: HabitList.Order? = null
|
||||
private var capturedSecondaryOrder: HabitList.Order? = null
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
every { adapter.setFilter(any()) } returns Unit
|
||||
every { adapter.refresh() } returns Unit
|
||||
behavior = ListHabitsMenuBehavior(screen, adapter, prefs, themeSwitcher)
|
||||
clearInvocations(adapter)
|
||||
resetCalls(adapter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInitialFilter() {
|
||||
whenever(prefs.showArchived).thenReturn(true)
|
||||
whenever(prefs.showCompleted).thenReturn(true)
|
||||
every { prefs.showArchived } returns true
|
||||
every { prefs.showCompleted } returns true
|
||||
every { adapter.setFilter(any()) } returns Unit
|
||||
every { adapter.refresh() } returns Unit
|
||||
behavior = ListHabitsMenuBehavior(screen, adapter, prefs, themeSwitcher)
|
||||
verify(adapter).setFilter(matcherCaptor.capture())
|
||||
verify(adapter).refresh()
|
||||
verifyNoMoreInteractions(adapter)
|
||||
clearInvocations(adapter)
|
||||
assertTrue(matcherCaptor.lastValue.isArchivedAllowed)
|
||||
assertTrue(matcherCaptor.lastValue.isCompletedAllowed)
|
||||
whenever(prefs.showArchived).thenReturn(false)
|
||||
whenever(prefs.showCompleted).thenReturn(false)
|
||||
verify { adapter.setFilter(any()) }
|
||||
verify { adapter.refresh() }
|
||||
verifyNoMoreCalls(adapter)
|
||||
resetCalls(adapter)
|
||||
every { prefs.showArchived } returns false
|
||||
every { prefs.showCompleted } returns false
|
||||
every { adapter.setFilter(any()) } returns Unit
|
||||
every { adapter.refresh() } returns Unit
|
||||
behavior = ListHabitsMenuBehavior(screen, adapter, prefs, themeSwitcher)
|
||||
verify(adapter).setFilter(matcherCaptor.capture())
|
||||
verify(adapter).refresh()
|
||||
verifyNoMoreInteractions(adapter)
|
||||
assertFalse(matcherCaptor.lastValue.isArchivedAllowed)
|
||||
assertFalse(matcherCaptor.lastValue.isCompletedAllowed)
|
||||
verify { adapter.setFilter(any()) }
|
||||
verify { adapter.refresh() }
|
||||
verifyNoMoreCalls(adapter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSortByColor() {
|
||||
behavior.onSortByColor()
|
||||
verify(adapter).primaryOrder = orderCaptor.capture()
|
||||
assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_COLOR_ASC))
|
||||
verify { adapter.primaryOrder = HabitList.Order.BY_COLOR_ASC }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSortManually() {
|
||||
behavior.onSortByManually()
|
||||
verify(adapter).primaryOrder = orderCaptor.capture()
|
||||
assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_POSITION))
|
||||
verify { adapter.primaryOrder = HabitList.Order.BY_POSITION }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSortScore() {
|
||||
behavior.onSortByScore()
|
||||
verify(adapter).primaryOrder = orderCaptor.capture()
|
||||
assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_SCORE_DESC))
|
||||
verify { adapter.primaryOrder = HabitList.Order.BY_SCORE_DESC }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSortName() {
|
||||
behavior.onSortByName()
|
||||
verify(adapter).primaryOrder = orderCaptor.capture()
|
||||
assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_NAME_ASC))
|
||||
verify { adapter.primaryOrder = HabitList.Order.BY_NAME_ASC }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSortStatus() {
|
||||
whenever(adapter.primaryOrder).thenReturn(HabitList.Order.BY_NAME_ASC)
|
||||
every { adapter.primaryOrder } returns HabitList.Order.BY_NAME_ASC
|
||||
behavior.onSortByStatus()
|
||||
verify(adapter).primaryOrder = orderCaptor.capture()
|
||||
verify(adapter).secondaryOrder = secondaryOrderCaptor.capture()
|
||||
assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_STATUS_ASC))
|
||||
assertThat(secondaryOrderCaptor.lastValue, equalTo(HabitList.Order.BY_NAME_ASC))
|
||||
verify { adapter.primaryOrder = HabitList.Order.BY_STATUS_ASC }
|
||||
verify { adapter.secondaryOrder = HabitList.Order.BY_NAME_ASC }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSortStatusToggle() {
|
||||
whenever(adapter.primaryOrder).thenReturn(HabitList.Order.BY_STATUS_ASC)
|
||||
every { adapter.primaryOrder } returns HabitList.Order.BY_STATUS_ASC
|
||||
behavior.onSortByStatus()
|
||||
verify(adapter).primaryOrder = orderCaptor.capture()
|
||||
verify(adapter, never()).secondaryOrder = any()
|
||||
assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_STATUS_DESC))
|
||||
verify { adapter.primaryOrder = HabitList.Order.BY_STATUS_DESC }
|
||||
verify(notCalled) { adapter.secondaryOrder = any() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnToggleShowArchived() {
|
||||
every { adapter.setFilter(any()) } returns Unit
|
||||
behavior.onToggleShowArchived()
|
||||
verify(adapter).setFilter(matcherCaptor.capture())
|
||||
assertTrue(matcherCaptor.lastValue.isArchivedAllowed)
|
||||
clearInvocations(adapter)
|
||||
verify { adapter.setFilter(any()) }
|
||||
resetCalls(adapter)
|
||||
every { adapter.setFilter(any()) } returns Unit
|
||||
behavior.onToggleShowArchived()
|
||||
verify(adapter).setFilter(matcherCaptor.capture())
|
||||
assertFalse(matcherCaptor.lastValue.isArchivedAllowed)
|
||||
verify { adapter.setFilter(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnToggleShowCompleted() {
|
||||
every { adapter.setFilter(any()) } returns Unit
|
||||
behavior.onToggleShowCompleted()
|
||||
verify(adapter).setFilter(matcherCaptor.capture())
|
||||
assertTrue(matcherCaptor.lastValue.isCompletedAllowed)
|
||||
clearInvocations(adapter)
|
||||
verify { adapter.setFilter(any()) }
|
||||
resetCalls(adapter)
|
||||
every { adapter.setFilter(any()) } returns Unit
|
||||
behavior.onToggleShowCompleted()
|
||||
verify(adapter).setFilter(matcherCaptor.capture())
|
||||
assertFalse(matcherCaptor.lastValue.isCompletedAllowed)
|
||||
verify { adapter.setFilter(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnViewAbout() {
|
||||
behavior.onViewAbout()
|
||||
verify(screen).showAboutScreen()
|
||||
verify { screen.showAboutScreen() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnViewFAQ() {
|
||||
behavior.onViewFAQ()
|
||||
verify(screen).showFAQScreen()
|
||||
verify { screen.showFAQScreen() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnViewSettings() {
|
||||
behavior.onViewSettings()
|
||||
verify(screen).showSettingsScreen()
|
||||
verify { screen.showSettingsScreen() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnToggleNightMode() {
|
||||
behavior.onToggleNightMode()
|
||||
verify(themeSwitcher).toggleNightMode()
|
||||
verify(screen).applyTheme()
|
||||
verify { themeSwitcher.toggleNightMode() }
|
||||
verify { screen.applyTheme() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,12 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.screens.habits.list
|
||||
|
||||
import dev.mokkery.answering.calls
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.matcher.any
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.Matchers.equalTo
|
||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
||||
@ -26,12 +32,6 @@ import org.isoron.uhabits.core.models.PaletteColor
|
||||
import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback
|
||||
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.KArgumentCaptor
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
@ -45,34 +45,30 @@ class ListHabitsSelectionMenuBehaviorTest : JvmBaseUnitTest() {
|
||||
private lateinit var habit2: Habit
|
||||
private lateinit var habit3: Habit
|
||||
|
||||
private val colorPickerCallback: KArgumentCaptor<OnColorPickedCallback> = argumentCaptor()
|
||||
|
||||
private val deleteCallback: KArgumentCaptor<OnConfirmedCallback> = argumentCaptor()
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun canArchive() {
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1, habit2))
|
||||
every { adapter.getSelected() } returns listOf(habit1, habit2)
|
||||
assertFalse(behavior.canArchive())
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit2, habit3))
|
||||
every { adapter.getSelected() } returns listOf(habit2, habit3)
|
||||
assertTrue(behavior.canArchive())
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun canEdit() {
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1))
|
||||
every { adapter.getSelected() } returns listOf(habit1)
|
||||
assertTrue(behavior.canEdit())
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1, habit2))
|
||||
every { adapter.getSelected() } returns listOf(habit1, habit2)
|
||||
assertFalse(behavior.canEdit())
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun canUnarchive() {
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1, habit2))
|
||||
every { adapter.getSelected() } returns listOf(habit1, habit2)
|
||||
assertFalse(behavior.canUnarchive())
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1))
|
||||
every { adapter.getSelected() } returns listOf(habit1)
|
||||
assertTrue(behavior.canUnarchive())
|
||||
}
|
||||
|
||||
@ -80,7 +76,7 @@ class ListHabitsSelectionMenuBehaviorTest : JvmBaseUnitTest() {
|
||||
@Throws(Exception::class)
|
||||
fun onArchiveHabits() {
|
||||
assertFalse(habit2.isArchived)
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit2))
|
||||
every { adapter.getSelected() } returns listOf(habit2)
|
||||
behavior.onArchiveHabits()
|
||||
assertTrue(habit2.isArchived)
|
||||
}
|
||||
@ -90,11 +86,14 @@ class ListHabitsSelectionMenuBehaviorTest : JvmBaseUnitTest() {
|
||||
fun onChangeColor() {
|
||||
assertThat(habit1.color, equalTo(PaletteColor(8)))
|
||||
assertThat(habit2.color, equalTo(PaletteColor(8)))
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1, habit2))
|
||||
every { adapter.getSelected() } returns listOf(habit1, habit2)
|
||||
every {
|
||||
screen.showColorPicker(any(), any())
|
||||
} calls { args ->
|
||||
val callback = args.arg<OnColorPickedCallback>(1)
|
||||
callback.onColorPicked(PaletteColor(30))
|
||||
}
|
||||
behavior.onChangeColor()
|
||||
verify(screen)
|
||||
.showColorPicker(eq(PaletteColor(8)), colorPickerCallback.capture())
|
||||
colorPickerCallback.lastValue.onColorPicked(PaletteColor(30))
|
||||
assertThat(habit1.color, equalTo(PaletteColor(30)))
|
||||
}
|
||||
|
||||
@ -103,10 +102,14 @@ class ListHabitsSelectionMenuBehaviorTest : JvmBaseUnitTest() {
|
||||
fun onDeleteHabits() {
|
||||
val id = habit1.id!!
|
||||
habitList.getById(id)!!
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1))
|
||||
every { adapter.getSelected() } returns listOf(habit1)
|
||||
every {
|
||||
screen.showDeleteConfirmationScreen(any(), any())
|
||||
} calls { args ->
|
||||
val callback = args.arg<OnConfirmedCallback>(0)
|
||||
callback.onConfirmed()
|
||||
}
|
||||
behavior.onDeleteHabits()
|
||||
verify(screen).showDeleteConfirmationScreen(deleteCallback.capture(), eq(1))
|
||||
deleteCallback.lastValue.onConfirmed()
|
||||
assertNull(habitList.getById(id))
|
||||
}
|
||||
|
||||
@ -114,16 +117,16 @@ class ListHabitsSelectionMenuBehaviorTest : JvmBaseUnitTest() {
|
||||
@Throws(Exception::class)
|
||||
fun onEditHabits() {
|
||||
val selected: List<Habit> = listOf(habit1, habit2)
|
||||
whenever(adapter.getSelected()).thenReturn(selected)
|
||||
every { adapter.getSelected() } returns selected
|
||||
behavior.onEditHabits()
|
||||
verify(screen).showEditHabitsScreen(selected)
|
||||
verify { screen.showEditHabitsScreen(selected) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun onUnarchiveHabits() {
|
||||
assertTrue(habit1.isArchived)
|
||||
whenever(adapter.getSelected()).thenReturn(listOf(habit1))
|
||||
every { adapter.getSelected() } returns listOf(habit1)
|
||||
behavior.onUnarchiveHabits()
|
||||
assertFalse(habit1.isArchived)
|
||||
}
|
||||
|
||||
@ -18,6 +18,10 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.screens.habits.show
|
||||
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
@ -25,9 +29,6 @@ import org.isoron.platform.io.JavaUserFile
|
||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
import java.nio.file.Files
|
||||
|
||||
class ShowHabitMenuPresenterTest : JvmBaseUnitTest() {
|
||||
@ -55,14 +56,14 @@ class ShowHabitMenuPresenterTest : JvmBaseUnitTest() {
|
||||
@Test
|
||||
fun testOnEditHabit() {
|
||||
menu.onEditHabit()
|
||||
verify(screen).showEditHabitScreen(habit)
|
||||
verify { screen.showEditHabitScreen(habit) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnExport() {
|
||||
val outputDir = Files.createTempDirectory("CSV").toFile()
|
||||
whenever(system.getCSVOutputDir()).thenReturn(JavaUserFile(outputDir.toPath()))
|
||||
every { system.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath())
|
||||
menu.onExportCSV()
|
||||
assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1))
|
||||
FileUtils.deleteDirectory(outputDir)
|
||||
|
||||
@ -19,6 +19,10 @@
|
||||
|
||||
package org.isoron.uhabits.core.ui.views
|
||||
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.resetCalls
|
||||
import dev.mokkery.verify
|
||||
import dev.mokkery.verifyNoMoreCalls
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.gui.assertRenders
|
||||
import org.isoron.platform.time.DayOfWeek
|
||||
@ -31,10 +35,6 @@ import org.isoron.uhabits.core.ui.views.HistoryChart.Square.HATCHED
|
||||
import org.isoron.uhabits.core.ui.views.HistoryChart.Square.OFF
|
||||
import org.isoron.uhabits.core.ui.views.HistoryChart.Square.ON
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.reset
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
import java.util.Locale
|
||||
|
||||
class HistoryChartTest {
|
||||
@ -89,29 +89,29 @@ class HistoryChartTest {
|
||||
|
||||
// Click top left date
|
||||
view.onClick(20.0, 46.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2014, 10, 26))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateShortPress(LocalDate(2014, 10, 26)) }
|
||||
resetCalls(dateClickedListener)
|
||||
view.onClick(2.0, 28.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2014, 10, 26))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateShortPress(LocalDate(2014, 10, 26)) }
|
||||
resetCalls(dateClickedListener)
|
||||
|
||||
// Click date in the middle
|
||||
view.onClick(163.0, 113.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2014, 12, 10))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateShortPress(LocalDate(2014, 12, 10)) }
|
||||
resetCalls(dateClickedListener)
|
||||
|
||||
// Click today
|
||||
view.onClick(336.0, 37.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2015, 1, 25))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateShortPress(LocalDate(2015, 1, 25)) }
|
||||
resetCalls(dateClickedListener)
|
||||
|
||||
// Click header
|
||||
view.onClick(160.0, 15.0)
|
||||
verifyNoMoreInteractions(dateClickedListener)
|
||||
verifyNoMoreCalls(dateClickedListener)
|
||||
|
||||
// Click right axis
|
||||
view.onClick(360.0, 60.0)
|
||||
verifyNoMoreInteractions(dateClickedListener)
|
||||
verifyNoMoreCalls(dateClickedListener)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -120,29 +120,29 @@ class HistoryChartTest {
|
||||
|
||||
// Click top left date
|
||||
view.onLongClick(20.0, 46.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2014, 10, 26))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateLongPress(LocalDate(2014, 10, 26)) }
|
||||
resetCalls(dateClickedListener)
|
||||
view.onLongClick(2.0, 28.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2014, 10, 26))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateLongPress(LocalDate(2014, 10, 26)) }
|
||||
resetCalls(dateClickedListener)
|
||||
|
||||
// Click date in the middle
|
||||
view.onLongClick(163.0, 113.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2014, 12, 10))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateLongPress(LocalDate(2014, 12, 10)) }
|
||||
resetCalls(dateClickedListener)
|
||||
|
||||
// Click today
|
||||
view.onLongClick(336.0, 37.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2015, 1, 25))
|
||||
reset(dateClickedListener)
|
||||
verify { dateClickedListener.onDateLongPress(LocalDate(2015, 1, 25)) }
|
||||
resetCalls(dateClickedListener)
|
||||
|
||||
// Click header
|
||||
view.onLongClick(160.0, 15.0)
|
||||
verifyNoMoreInteractions(dateClickedListener)
|
||||
verifyNoMoreCalls(dateClickedListener)
|
||||
|
||||
// Click right axis
|
||||
view.onLongClick(360.0, 60.0)
|
||||
verifyNoMoreInteractions(dateClickedListener)
|
||||
verifyNoMoreCalls(dateClickedListener)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -18,6 +18,11 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.widgets
|
||||
|
||||
import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.resetCalls
|
||||
import dev.mokkery.verify
|
||||
import org.isoron.platform.time.LocalDate
|
||||
import org.isoron.platform.time.getToday
|
||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
||||
@ -29,11 +34,7 @@ import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.ui.NotificationTray
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.reset
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoInteractions
|
||||
import org.mockito.kotlin.whenever
|
||||
import dev.mokkery.verify.VerifyMode.Companion.not as notCalled
|
||||
|
||||
class WidgetBehaviorTest : JvmBaseUnitTest() {
|
||||
private lateinit var notificationTray: NotificationTray
|
||||
@ -57,21 +58,25 @@ class WidgetBehaviorTest : JvmBaseUnitTest() {
|
||||
@Test
|
||||
fun testOnAddRepetition() {
|
||||
behavior.onAddRepetition(habit, today)
|
||||
verify(commandRunner).run(
|
||||
CreateRepetitionCommand(habitList, habit, today, Entry.YES_MANUAL, "")
|
||||
)
|
||||
verify(notificationTray).cancel(habit)
|
||||
verifyNoInteractions(preferences)
|
||||
verify {
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(habitList, habit, today, Entry.YES_MANUAL, "")
|
||||
)
|
||||
}
|
||||
verify { notificationTray.cancel(habit) }
|
||||
verify(notCalled) { preferences.isSkipEnabled }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnRemoveRepetition() {
|
||||
behavior.onRemoveRepetition(habit, today)
|
||||
verify(commandRunner).run(
|
||||
CreateRepetitionCommand(habitList, habit, today, Entry.NO, "")
|
||||
)
|
||||
verify(notificationTray).cancel(habit)
|
||||
verifyNoInteractions(preferences)
|
||||
verify {
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(habitList, habit, today, Entry.NO, "")
|
||||
)
|
||||
}
|
||||
verify { notificationTray.cancel(habit) }
|
||||
verify(notCalled) { preferences.isSkipEnabled }
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -84,7 +89,7 @@ class WidgetBehaviorTest : JvmBaseUnitTest() {
|
||||
Entry.SKIP
|
||||
)
|
||||
) {
|
||||
whenever(preferences.isSkipEnabled).thenReturn(skipEnabled)
|
||||
every { preferences.isSkipEnabled } returns skipEnabled
|
||||
val nextValue: Int = nextToggleValue(
|
||||
currentValue,
|
||||
isSkipEnabled = skipEnabled,
|
||||
@ -92,14 +97,18 @@ class WidgetBehaviorTest : JvmBaseUnitTest() {
|
||||
)
|
||||
habit.originalEntries.add(Entry(today, currentValue))
|
||||
behavior.onToggleRepetition(habit, today)
|
||||
verify(preferences).isSkipEnabled
|
||||
verify(commandRunner).run(
|
||||
CreateRepetitionCommand(habitList, habit, today, nextValue, "")
|
||||
)
|
||||
verify(notificationTray).cancel(
|
||||
habit
|
||||
)
|
||||
reset(preferences, commandRunner, notificationTray)
|
||||
verify { preferences.isSkipEnabled }
|
||||
verify {
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(habitList, habit, today, nextValue, "")
|
||||
)
|
||||
}
|
||||
verify {
|
||||
notificationTray.cancel(
|
||||
habit
|
||||
)
|
||||
}
|
||||
resetCalls(preferences, commandRunner, notificationTray)
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,11 +118,13 @@ class WidgetBehaviorTest : JvmBaseUnitTest() {
|
||||
habit.originalEntries.add(Entry(today, 500))
|
||||
habit.recompute()
|
||||
behavior.onIncrement(habit, today, 100)
|
||||
verify(commandRunner).run(
|
||||
CreateRepetitionCommand(habitList, habit, today, 600, "")
|
||||
)
|
||||
verify(notificationTray).cancel(habit)
|
||||
verifyNoInteractions(preferences)
|
||||
verify {
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(habitList, habit, today, 600, "")
|
||||
)
|
||||
}
|
||||
verify { notificationTray.cancel(habit) }
|
||||
verify(notCalled) { preferences.isSkipEnabled }
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -122,10 +133,12 @@ class WidgetBehaviorTest : JvmBaseUnitTest() {
|
||||
habit.originalEntries.add(Entry(today, 500))
|
||||
habit.recompute()
|
||||
behavior.onDecrement(habit, today, 100)
|
||||
verify(commandRunner).run(
|
||||
CreateRepetitionCommand(habitList, habit, today, 400, "")
|
||||
)
|
||||
verify(notificationTray).cancel(habit)
|
||||
verifyNoInteractions(preferences)
|
||||
verify {
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(habitList, habit, today, 400, "")
|
||||
)
|
||||
}
|
||||
verify { notificationTray.cancel(habit) }
|
||||
verify(notCalled) { preferences.isSkipEnabled }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.isoron.uhabits.core.utils
|
||||
|
||||
import dev.mokkery.mock
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -9,7 +10,6 @@ import org.isoron.uhabits.core.io.StandardLogging
|
||||
import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.mock
|
||||
import java.util.Calendar
|
||||
import java.util.TimeZone
|
||||
import java.util.concurrent.Executors
|
||||
@ -20,8 +20,7 @@ import kotlin.test.assertEquals
|
||||
class MidnightTimerTest : JvmBaseUnitTest() {
|
||||
|
||||
@After
|
||||
override fun tearDown() {
|
||||
super.tearDown()
|
||||
fun tearDown() {
|
||||
DateUtils.setFixedLocalTime(null)
|
||||
DateUtils.setFixedTimeZone(null)
|
||||
}
|
||||
@ -46,7 +45,7 @@ class MidnightTimerTest : JvmBaseUnitTest() {
|
||||
)
|
||||
|
||||
val suspendedListener = suspendCoroutine<Boolean> { continuation ->
|
||||
MidnightTimer(StandardLogging(), mock(Preferences::class.java)).apply {
|
||||
MidnightTimer(StandardLogging(), mock<Preferences>()).apply {
|
||||
addListener { continuation.resume(true) }
|
||||
// When
|
||||
onResume(1, executor)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user