Clean up kotlin code

* static imports
* less nullable types
* format
pull/709/head
Quentin Hibon 5 years ago
parent 9d0fbb9ea9
commit dedeb13f46

@ -125,6 +125,7 @@ dependencies {
testImplementation "junit:junit:4.12" testImplementation "junit:junit:4.12"
testImplementation "org.mockito:mockito-core:2.28.2" testImplementation "org.mockito:mockito-core:2.28.2"
testImplementation "org.mockito:mockito-inline:2.8.9" testImplementation "org.mockito:mockito-inline:2.8.9"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
} }
kapt { kapt {

@ -38,19 +38,13 @@ import org.mockito.Mockito.mock
@Module @Module
class TestModule { class TestModule {
@Provides fun ListHabitsBehavior() = mock(ListHabitsBehavior::class.java) @Provides fun listHabitsBehavior(): ListHabitsBehavior = mock(ListHabitsBehavior::class.java)
} }
@ActivityScope @ActivityScope
@Component( @Component(
modules = arrayOf( modules = [ActivityContextModule::class, HabitsActivityModule::class, ListHabitsModule::class, HabitModule::class, TestModule::class],
ActivityContextModule::class, dependencies = [HabitsApplicationComponent::class]
HabitsActivityModule::class,
ListHabitsModule::class,
HabitModule::class,
TestModule::class
),
dependencies = arrayOf(HabitsApplicationComponent::class)
) )
interface HabitsActivityTestComponent { interface HabitsActivityTestComponent {
fun getCheckmarkPanelViewFactory(): CheckmarkPanelViewFactory fun getCheckmarkPanelViewFactory(): CheckmarkPanelViewFactory

@ -25,7 +25,8 @@ import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction import androidx.test.espresso.ViewAction
import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.endsWith
import org.hamcrest.Matcher import org.hamcrest.Matcher
import org.isoron.uhabits.BaseUserInterfaceTest import org.isoron.uhabits.BaseUserInterfaceTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
@ -56,12 +57,12 @@ object ListHabitsSteps {
private fun clickTextInsideOverflowMenu(id: Int) { private fun clickTextInsideOverflowMenu(id: Int) {
Espresso.onView( Espresso.onView(
CoreMatchers.allOf( allOf(
ViewMatchers.withContentDescription("More options"), ViewMatchers.withContentDescription("More options"),
ViewMatchers.withParent( ViewMatchers.withParent(
ViewMatchers.withParent( ViewMatchers.withParent(
ViewMatchers.withClassName( ViewMatchers.withClassName(
CoreMatchers.endsWith("Toolbar") endsWith("Toolbar")
) )
) )
) )
@ -107,9 +108,9 @@ object ListHabitsSteps {
fun longPressCheckmarks(habit: String?, count: Int) { fun longPressCheckmarks(habit: String?, count: Int) {
CommonSteps.scrollToText(habit) CommonSteps.scrollToText(habit)
Espresso.onView( Espresso.onView(
CoreMatchers.allOf( allOf(
ViewMatchers.hasDescendant(ViewMatchers.withText(habit)), ViewMatchers.hasDescendant(ViewMatchers.withText(habit)),
ViewMatchers.withClassName(CoreMatchers.endsWith("HabitCardView")) ViewMatchers.withClassName(endsWith("HabitCardView"))
) )
).perform( ).perform(
longClickDescendantWithClass(CheckmarkButtonView::class.java, count) longClickDescendantWithClass(CheckmarkButtonView::class.java, count)

@ -28,8 +28,8 @@ import org.isoron.uhabits.BaseUserInterfaceTest
object WidgetSteps { object WidgetSteps {
@Throws(Exception::class) @Throws(Exception::class)
fun clickCheckmarkWidget() { fun clickCheckmarkWidget() {
val view_id = "org.isoron.uhabits:id/imageView" val viewId = "org.isoron.uhabits:id/imageView"
BaseUserInterfaceTest.device.findObject(UiSelector().resourceId(view_id)).click() BaseUserInterfaceTest.device.findObject(UiSelector().resourceId(viewId)).click()
} }
@Throws(Exception::class) @Throws(Exception::class)
@ -66,7 +66,7 @@ object WidgetSteps {
BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click() BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click()
BaseUserInterfaceTest.device.findObject(UiSelector().description("Widgets")).click() BaseUserInterfaceTest.device.findObject(UiSelector().description("Widgets")).click()
} else { } else {
val list_id = "com.android.launcher3:id/widgets_list_view" val listId = "com.android.launcher3:id/widgets_list_view"
BaseUserInterfaceTest.device.pressHome() BaseUserInterfaceTest.device.pressHome()
BaseUserInterfaceTest.device.waitForIdle() BaseUserInterfaceTest.device.waitForIdle()
BaseUserInterfaceTest.device.drag(w / 2, h / 2, w / 2, h / 2, 8) BaseUserInterfaceTest.device.drag(w / 2, h / 2, w / 2, h / 2, 8)
@ -76,10 +76,10 @@ object WidgetSteps {
} }
button.click() button.click()
if (VERSION.SDK_INT >= 28) { if (VERSION.SDK_INT >= 28) {
UiScrollable(UiSelector().resourceId(list_id)) UiScrollable(UiSelector().resourceId(listId))
.scrollForward() .scrollForward()
} }
UiScrollable(UiSelector().resourceId(list_id)) UiScrollable(UiSelector().resourceId(listId))
.scrollIntoView(UiSelector().text("Checkmark")) .scrollIntoView(UiSelector().text("Checkmark"))
} }
} }

@ -34,11 +34,12 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
private const val PATH = "habits/list/CheckmarkPanelView"
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@MediumTest @MediumTest
class EntryPanelViewTest : BaseViewTest() { class EntryPanelViewTest : BaseViewTest() {
private val PATH = "habits/list/CheckmarkPanelView"
private lateinit var view: CheckmarkPanelView private lateinit var view: CheckmarkPanelView
@Before @Before
@ -75,27 +76,6 @@ class EntryPanelViewTest : BaseViewTest() {
assertRenders(view, "$PATH/render.png") assertRenders(view, "$PATH/render.png")
} }
// // Flaky test
// @Test
// fun testRender_withDifferentColor() {
// view.color = PaletteUtils.getAndroidTestColor(1)
// assertRenders(view, "$PATH/render_different_color.png")
// }
// // Flaky test
// @Test
// fun testRender_Reversed() {
// prefs.isCheckmarkSequenceReversed = true
// assertRenders(view, "$PATH/render_reversed.png")
// }
// // Flaky test
// @Test
// fun testRender_withOffset() {
// view.dataOffset = 3
// assertRenders(view, "$PATH/render_offset.png")
// }
@Test @Test
fun testToggle() { fun testToggle() {
val timestamps = mutableListOf<Timestamp>() val timestamps = mutableListOf<Timestamp>()

@ -56,7 +56,7 @@ class HabitCardViewTest : BaseViewTest() {
view = component.getHabitCardViewFactory().create().apply { view = component.getHabitCardViewFactory().create().apply {
habit = habit1 habit = habit1
values = entries values = entries
score = habit1.scores.get(today).value score = habit1.scores[today].value
isSelected = false isSelected = false
buttonCount = 5 buttonCount = 5
} }

@ -73,27 +73,6 @@ class NumberPanelViewTest : BaseViewTest() {
assertRenders(view, "$PATH/render.png") assertRenders(view, "$PATH/render.png")
} }
// // Flaky test
// @Test
// fun testRender_withDifferentColor() {
// view.color = PaletteUtils.getAndroidTestColor(1)
// assertRenders(view, "$PATH/render_different_color.png")
// }
// // Flaky test
// @Test
// fun testRender_Reversed() {
// prefs.isCheckmarkSequenceReversed = true
// assertRenders(view, "$PATH/render_reversed.png")
// }
// // Flaky test
// @Test
// fun testRender_withOffset() {
// view.dataOffset = 3
// assertRenders(view, "$PATH/render_offset.png")
// }
@Test @Test
fun testEdit() { fun testEdit() {
val timestamps = mutableListOf<Timestamp>() val timestamps = mutableListOf<Timestamp>()

@ -103,9 +103,8 @@ class IntentSchedulerTest : BaseAndroidTest() {
assertNull(ReminderReceiver.lastReceivedIntent) assertNull(ReminderReceiver.lastReceivedIntent)
setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46) setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46)
val intent = ReminderReceiver.lastReceivedIntent val intent = ReminderReceiver.lastReceivedIntent!!
assertNotNull(intent) assertThat(parseId(intent.data!!), equalTo(habit.id))
assertThat(parseId(intent?.data!!), equalTo(habit.id))
} }
@Test @Test
@ -123,7 +122,6 @@ class IntentSchedulerTest : BaseAndroidTest() {
assertNull(WidgetReceiver.lastReceivedIntent) assertNull(WidgetReceiver.lastReceivedIntent)
setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46) setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46)
val intent = WidgetReceiver.lastReceivedIntent WidgetReceiver.lastReceivedIntent!!
assertNotNull(intent)
} }
} }

@ -68,13 +68,6 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
assertRenders(view, PATH + "checked.png"); assertRenders(view, PATH + "checked.png");
} }
// @Test
// public void testRender_implicitlyChecked() throws IOException
// {
// view.setCheckmarkValue(Checkmark.YES_AUTO);
// view.refresh();
// assertRenders(view, PATH + "implicitly_checked.png");
// }
@Test @Test
public void testRender_largeSize() throws IOException public void testRender_largeSize() throws IOException
@ -83,11 +76,4 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
assertRenders(view, PATH + "large_size.png"); assertRenders(view, PATH + "large_size.png");
} }
// @Test
// public void testRender_unchecked() throws IOException
// {
// view.setCheckmarkValue(Checkmark.NO);
// view.refresh();
// assertRenders(view, PATH + "unchecked.png");
// }
} }

@ -25,6 +25,8 @@ import android.util.AttributeSet
import android.view.GestureDetector import android.view.GestureDetector
import android.view.MotionEvent import android.view.MotionEvent
import android.widget.Scroller import android.widget.Scroller
import kotlin.math.abs
import kotlin.math.max
/** /**
* An AndroidView that implements scrolling. * An AndroidView that implements scrolling.
@ -71,7 +73,7 @@ class AndroidDataView(
dx: Float, dx: Float,
dy: Float, dy: Float,
): Boolean { ): Boolean {
if (Math.abs(dx) > Math.abs(dy)) { if (abs(dx) > abs(dy)) {
val parent = parent val parent = parent
parent?.requestDisallowInterceptTouchEvent(true) parent?.requestDisallowInterceptTouchEvent(true)
} }
@ -128,7 +130,7 @@ class AndroidDataView(
view?.let { v -> view?.let { v ->
var newDataOffset: Int = var newDataOffset: Int =
scroller.currX / (v.dataColumnWidth * canvas.innerDensity).toInt() scroller.currX / (v.dataColumnWidth * canvas.innerDensity).toInt()
newDataOffset = Math.max(0, newDataOffset) newDataOffset = max(0, newDataOffset)
if (newDataOffset != v.dataOffset) { if (newDataOffset != v.dataOffset) {
v.dataOffset = newDataOffset v.dataOffset = newDataOffset
postInvalidate() postInvalidate()

@ -42,7 +42,7 @@ class AndroidImage(private val bmp: Bitmap) : Image {
} }
} }
public fun Color.toInt(): Int { fun Color.toInt(): Int {
return android.graphics.Color.argb( return android.graphics.Color.argb(
(255 * this.alpha).roundToInt(), (255 * this.alpha).roundToInt(),
(255 * this.red).roundToInt(), (255 * this.red).roundToInt(),

@ -83,7 +83,7 @@ class HabitsApplication : Application() {
notificationTray.startListening() notificationTray.startListening()
val prefs = component.preferences val prefs = component.preferences
prefs.setLastAppVersion(BuildConfig.VERSION_CODE) prefs.lastAppVersion = BuildConfig.VERSION_CODE
val taskRunner = component.taskRunner val taskRunner = component.taskRunner
taskRunner.execute { taskRunner.execute {
@ -106,11 +106,11 @@ class HabitsApplication : Application() {
lateinit var component: HabitsApplicationComponent lateinit var component: HabitsApplicationComponent
fun isTestMode(): Boolean { fun isTestMode(): Boolean {
try { return try {
Class.forName("org.isoron.uhabits.BaseAndroidTest") Class.forName("org.isoron.uhabits.BaseAndroidTest")
return true true
} catch (e: ClassNotFoundException) { } catch (e: ClassNotFoundException) {
return false false
} }
} }
} }

@ -34,6 +34,7 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils import org.isoron.uhabits.utils.InterfaceUtils
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.roundToLong
class NumberPickerFactory class NumberPickerFactory
@Inject constructor( @Inject constructor(
@ -52,7 +53,7 @@ class NumberPickerFactory
val picker2 = view.findViewById<NumberPicker>(R.id.picker2) val picker2 = view.findViewById<NumberPicker>(R.id.picker2)
val tvUnit = view.findViewById<TextView>(R.id.tvUnit) val tvUnit = view.findViewById<TextView>(R.id.tvUnit)
val intValue = Math.round(value * 100).toInt() val intValue = (value * 100).roundToLong().toInt()
picker.minValue = 0 picker.minValue = 0
picker.maxValue = Integer.MAX_VALUE / 100 picker.maxValue = Integer.MAX_VALUE / 100
@ -86,13 +87,12 @@ class NumberPickerFactory
} }
InterfaceUtils.setupEditorAction( InterfaceUtils.setupEditorAction(
picker, picker
TextView.OnEditorActionListener { _, actionId, _ -> ) { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) if (actionId == EditorInfo.IME_ACTION_DONE)
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick() dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
false false
} }
)
return dialog return dialog
} }

@ -56,8 +56,7 @@ class TaskProgressBar(
fun update() { fun update() {
val callback = { val callback = {
val activeTaskCount = runner.activeTaskCount val newVisibility = when (runner.activeTaskCount) {
val newVisibility = when (activeTaskCount) {
0 -> GONE 0 -> GONE
else -> VISIBLE else -> VISIBLE
} }

@ -36,7 +36,7 @@ class HabitTypeDialog : AppCompatDialogFragment() {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val binding = SelectHabitTypeBinding.inflate(inflater, container, false) val binding = SelectHabitTypeBinding.inflate(inflater, container, false)
binding.buttonYesNo.setOnClickListener { binding.buttonYesNo.setOnClickListener {

@ -48,9 +48,9 @@ import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.dp import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
import org.isoron.uhabits.utils.sres import org.isoron.uhabits.utils.sres
import java.lang.Math.max
import java.lang.Math.min
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.max
import kotlin.math.min
const val MAX_CHECKMARK_COUNT = 60 const val MAX_CHECKMARK_COUNT = 60

@ -39,12 +39,10 @@ class HabitCardListController @Inject constructor(
private val selectionMenu: Lazy<ListHabitsSelectionMenu> private val selectionMenu: Lazy<ListHabitsSelectionMenu>
) : HabitCardListView.Controller, ModelObservable.Listener { ) : HabitCardListView.Controller, ModelObservable.Listener {
private val NORMAL_MODE = NormalMode()
private val SELECTION_MODE = SelectionMode()
private var activeMode: Mode private var activeMode: Mode
init { init {
this.activeMode = NORMAL_MODE this.activeMode = NormalMode()
adapter.observable.addListener(this) adapter.observable.addListener(this)
} }
@ -83,9 +81,9 @@ class HabitCardListController @Inject constructor(
activeMode.startDrag(position) activeMode.startDrag(position)
} }
protected fun toggleSelection(position: Int) { private fun toggleSelection(position: Int) {
adapter.toggleSelection(position) adapter.toggleSelection(position)
activeMode = if (adapter.isSelectionEmpty) NORMAL_MODE else SELECTION_MODE activeMode = if (adapter.isSelectionEmpty) NormalMode() else SelectionMode()
} }
private fun cancelSelection() { private fun cancelSelection() {
@ -116,8 +114,7 @@ class HabitCardListController @Inject constructor(
*/ */
internal inner class NormalMode : Mode { internal inner class NormalMode : Mode {
override fun onItemClick(position: Int) { override fun onItemClick(position: Int) {
val habit = adapter.getItem(position) val habit = adapter.getItem(position) ?: return
if (habit == null) return
behavior.onClickHabit(habit) behavior.onClickHabit(habit)
} }
@ -130,9 +127,9 @@ class HabitCardListController @Inject constructor(
startSelection(position) startSelection(position)
} }
protected fun startSelection(position: Int) { private fun startSelection(position: Int) {
toggleSelection(position) toggleSelection(position)
activeMode = SELECTION_MODE activeMode = SelectionMode()
selectionMenu.get().onSelectionStart() selectionMenu.get().onSelectionStart()
} }
} }
@ -158,8 +155,8 @@ class HabitCardListController @Inject constructor(
notifyListener() notifyListener()
} }
protected fun notifyListener() { private fun notifyListener() {
if (activeMode === SELECTION_MODE) if (activeMode === SelectionMode())
selectionMenu.get().onSelectionChange() selectionMenu.get().onSelectionChange()
else else
selectionMenu.get().onSelectionFinish() selectionMenu.get().onSelectionFinish()

@ -170,22 +170,22 @@ class HabitCardListView(
inner class TouchHelperCallback : ItemTouchHelper.Callback() { inner class TouchHelperCallback : ItemTouchHelper.Callback() {
override fun getMovementFlags( override fun getMovementFlags(
recyclerView: RecyclerView, recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder viewHolder: ViewHolder
): Int { ): Int {
return makeMovementFlags(UP or DOWN, START or END) return makeMovementFlags(UP or DOWN, START or END)
} }
override fun onMove( override fun onMove(
recyclerView: RecyclerView, recyclerView: RecyclerView,
from: RecyclerView.ViewHolder, from: ViewHolder,
to: RecyclerView.ViewHolder to: ViewHolder
): Boolean { ): Boolean {
controller.get().drop(from.adapterPosition, to.adapterPosition) controller.get().drop(from.adapterPosition, to.adapterPosition)
return true return true
} }
override fun onSwiped( override fun onSwiped(
viewHolder: RecyclerView.ViewHolder, viewHolder: ViewHolder,
direction: Int direction: Int
) { ) {
} }

@ -59,8 +59,8 @@ class HabitCardViewFactory
class HabitCardView( class HabitCardView(
@ActivityContext context: Context, @ActivityContext context: Context,
private val checkmarkPanelFactory: CheckmarkPanelViewFactory, checkmarkPanelFactory: CheckmarkPanelViewFactory,
private val numberPanelFactory: NumberPanelViewFactory, numberPanelFactory: NumberPanelViewFactory,
private val behavior: ListHabitsBehavior private val behavior: ListHabitsBehavior
) : FrameLayout(context), ) : FrameLayout(context),
ModelObservable.Listener { ModelObservable.Listener {
@ -174,7 +174,7 @@ class HabitCardView(
} }
clipToPadding = false clipToPadding = false
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT) layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
val margin = dp(3f).toInt() val margin = dp(3f).toInt()
setPadding(margin, 0, margin, margin) setPadding(margin, 0, margin, margin)
addView(innerFrame) addView(innerFrame)

@ -71,7 +71,7 @@ class NumberPanelView(
setupButtons() setupButtons()
} }
override fun createButton() = buttonFactory.create()!! override fun createButton() = buttonFactory.create()
@Synchronized @Synchronized
override fun setupButtons() { override fun setupButtons() {

@ -27,6 +27,7 @@ import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState
import org.isoron.uhabits.databinding.ShowHabitOverviewBinding import org.isoron.uhabits.databinding.ShowHabitOverviewBinding
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.toThemedAndroidColor import org.isoron.uhabits.utils.toThemedAndroidColor
import kotlin.math.abs
class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@ -36,7 +37,7 @@ class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
return String.format( return String.format(
"%s%.0f%%", "%s%.0f%%",
if (percentageDiff >= 0) "+" else "\u2212", if (percentageDiff >= 0) "+" else "\u2212",
Math.abs(percentageDiff) * 100 abs(percentageDiff) * 100
) )
} }

@ -68,7 +68,7 @@ class SyncActivity : AppCompatActivity(), SyncBehavior.Screen {
title = resources.getString(R.string.device_sync), title = resources.getString(R.string.device_sync),
) )
binding.syncLink.setOnClickListener { copyToClipboard() } binding.syncLink.setOnClickListener { copyToClipboard() }
binding.instructions.setText(Html.fromHtml(resources.getString(R.string.sync_instructions))) binding.instructions.text = Html.fromHtml(resources.getString(R.string.sync_instructions))
setContentView(binding.root) setContentView(binding.root)
} }

@ -27,22 +27,22 @@ class AndroidCursor(private val cursor: android.database.Cursor) : Cursor {
override fun moveToNext() = cursor.moveToNext() override fun moveToNext() = cursor.moveToNext()
override fun getInt(index: Int): Int? { override fun getInt(index: Int): Int? {
if (cursor.isNull(index)) return null return if (cursor.isNull(index)) null
else return cursor.getInt(index) else cursor.getInt(index)
} }
override fun getLong(index: Int): Long? { override fun getLong(index: Int): Long? {
if (cursor.isNull(index)) return null return if (cursor.isNull(index)) null
else return cursor.getLong(index) else cursor.getLong(index)
} }
override fun getDouble(index: Int): Double? { override fun getDouble(index: Int): Double? {
if (cursor.isNull(index)) return null return if (cursor.isNull(index)) null
else return cursor.getDouble(index) else cursor.getDouble(index)
} }
override fun getString(index: Int): String? { override fun getString(index: Int): String? {
if (cursor.isNull(index)) return null return if (cursor.isNull(index)) null
else return cursor.getString(index) else cursor.getString(index)
} }
} }

@ -51,7 +51,7 @@ class AndroidDatabase(
return db.update(tableName, contValues, where, params) return db.update(tableName, contValues, where, params)
} }
override fun insert(tableName: String, values: Map<String, Any?>): Long? { override fun insert(tableName: String, values: Map<String, Any?>): Long {
val contValues = mapToContentValues(values) val contValues = mapToContentValues(values)
return db.insert(tableName, null, contValues) return db.insert(tableName, null, contValues)
} }

@ -32,13 +32,8 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
@ActivityScope @ActivityScope
@Component( @Component(
modules = arrayOf( modules = [ActivityContextModule::class, HabitsActivityModule::class, ListHabitsModule::class, HabitModule::class],
ActivityContextModule::class, dependencies = [HabitsApplicationComponent::class]
HabitsActivityModule::class,
ListHabitsModule::class,
HabitModule::class
),
dependencies = arrayOf(HabitsApplicationComponent::class)
) )
interface HabitsActivityComponent { interface HabitsActivityComponent {
val colorPickerDialogFactory: ColorPickerDialogFactory val colorPickerDialogFactory: ColorPickerDialogFactory

@ -44,9 +44,8 @@ class IntentParser
} }
private fun parseHabit(uri: Uri): Habit { private fun parseHabit(uri: Uri): Habit {
val habit = habits.getById(parseId(uri)) return habits.getById(parseId(uri))
?: throw IllegalArgumentException("habit not found") ?: throw IllegalArgumentException("habit not found")
return habit
} }
private fun parseTimestamp(intent: Intent): Timestamp { private fun parseTimestamp(intent: Intent): Timestamp {

@ -36,6 +36,7 @@ import org.isoron.uhabits.core.utils.DateFormats
import org.isoron.uhabits.inject.AppContext import org.isoron.uhabits.inject.AppContext
import java.util.Date import java.util.Date
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.min
@AppScope @AppScope
class IntentScheduler class IntentScheduler
@ -84,7 +85,7 @@ class IntentScheduler
} }
private fun logReminderScheduled(habit: Habit, reminderTime: Long) { private fun logReminderScheduled(habit: Habit, reminderTime: Long) {
val min = Math.min(5, habit.name.length) val min = min(5, habit.name.length)
val name = habit.name.substring(0, min) val name = habit.name.substring(0, min)
val df = DateFormats.getBackupDateFormat() val df = DateFormats.getBackupDateFormat()
val time = df.format(Date(reminderTime)) val time = df.format(Date(reminderTime))

@ -41,7 +41,7 @@ class PendingIntentFactory
) { ) {
fun addCheckmark(habit: Habit, timestamp: Timestamp?): PendingIntent = fun addCheckmark(habit: Habit, timestamp: Timestamp?): PendingIntent =
PendingIntent.getBroadcast( getBroadcast(
context, context,
1, 1,
Intent(context, WidgetReceiver::class.java).apply { Intent(context, WidgetReceiver::class.java).apply {
@ -53,7 +53,7 @@ class PendingIntentFactory
) )
fun dismissNotification(habit: Habit): PendingIntent = fun dismissNotification(habit: Habit): PendingIntent =
PendingIntent.getBroadcast( getBroadcast(
context, context,
0, 0,
Intent(context, ReminderReceiver::class.java).apply { Intent(context, ReminderReceiver::class.java).apply {
@ -64,7 +64,7 @@ class PendingIntentFactory
) )
fun removeRepetition(habit: Habit): PendingIntent = fun removeRepetition(habit: Habit): PendingIntent =
PendingIntent.getBroadcast( getBroadcast(
context, context,
3, 3,
Intent(context, WidgetReceiver::class.java).apply { Intent(context, WidgetReceiver::class.java).apply {
@ -90,7 +90,7 @@ class PendingIntentFactory
reminderTime: Long?, reminderTime: Long?,
timestamp: Long timestamp: Long
): PendingIntent = ): PendingIntent =
PendingIntent.getBroadcast( getBroadcast(
context, context,
(habit.id!! % Integer.MAX_VALUE).toInt() + 1, (habit.id!! % Integer.MAX_VALUE).toInt() + 1,
Intent(context, ReminderReceiver::class.java).apply { Intent(context, ReminderReceiver::class.java).apply {
@ -103,7 +103,7 @@ class PendingIntentFactory
) )
fun snoozeNotification(habit: Habit): PendingIntent = fun snoozeNotification(habit: Habit): PendingIntent =
PendingIntent.getBroadcast( getBroadcast(
context, context,
0, 0,
Intent(context, ReminderReceiver::class.java).apply { Intent(context, ReminderReceiver::class.java).apply {
@ -114,7 +114,7 @@ class PendingIntentFactory
) )
fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent = fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent =
PendingIntent.getBroadcast( getBroadcast(
context, context,
2, 2,
Intent(context, WidgetReceiver::class.java).apply { Intent(context, WidgetReceiver::class.java).apply {
@ -145,7 +145,7 @@ class PendingIntentFactory
) )
fun updateWidgets(): PendingIntent = fun updateWidgets(): PendingIntent =
PendingIntent.getBroadcast( getBroadcast(
context, context,
0, 0,
Intent(context, WidgetReceiver::class.java).apply { Intent(context, WidgetReceiver::class.java).apply {

@ -40,17 +40,17 @@ class RingtoneManager
PreferenceManager.getDefaultSharedPreferences(context) PreferenceManager.getDefaultSharedPreferences(context)
fun getName(): String? { fun getName(): String? {
try { return try {
var ringtoneName = context.resources.getString(R.string.none) var ringtoneName = context.resources.getString(R.string.none)
val ringtoneUri = getURI() val ringtoneUri = getURI()
if (ringtoneUri != null) { if (ringtoneUri != null) {
val ringtone = getRingtone(context, ringtoneUri) val ringtone = getRingtone(context, ringtoneUri)
if (ringtone != null) ringtoneName = ringtone.getTitle(context) if (ringtone != null) ringtoneName = ringtone.getTitle(context)
} }
return ringtoneName ringtoneName
} catch (e: RuntimeException) { } catch (e: RuntimeException) {
e.printStackTrace() e.printStackTrace()
return null null
} }
} }

@ -80,8 +80,7 @@ class RemoteSyncServer(
try { try {
val url = "${preferences.syncBaseURL}/db/$key" val url = "${preferences.syncBaseURL}/db/$key"
Log.i("RemoteSyncServer", "GET $url") Log.i("RemoteSyncServer", "GET $url")
val data: SyncData = httpClient.get(url) return@IO httpClient.get<SyncData>(url)
return@IO data
} catch (e: ServerResponseException) { } catch (e: ServerResponseException) {
throw ServiceUnavailable() throw ServiceUnavailable()
} catch (e: ClientRequestException) { } catch (e: ClientRequestException) {

@ -23,7 +23,7 @@ import android.content.Context
class CheckmarkWidgetProvider : BaseWidgetProvider() { class CheckmarkWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget { override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id) val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return CheckmarkWidget(context, id, habits[0]) return if (habits.size == 1) CheckmarkWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.CHECKMARK, habits) else StackWidget(context, id, StackWidgetType.CHECKMARK, habits)
} }
} }

@ -36,7 +36,7 @@ class FrequencyWidget(
override val defaultHeight: Int = 200 override val defaultHeight: Int = 200
override val defaultWidth: Int = 200 override val defaultWidth: Int = 200
override fun getOnClickPendingIntent(context: Context): PendingIntent? = override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit) pendingIntentFactory.showHabit(habit)
override fun refreshData(v: View) { override fun refreshData(v: View) {

@ -24,12 +24,12 @@ import android.content.Context
class FrequencyWidgetProvider : BaseWidgetProvider() { class FrequencyWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget { override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id) val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return FrequencyWidget( return if (habits.size == 1) FrequencyWidget(
context, context,
id, id,
habits[0], habits[0],
preferences!!.firstWeekdayInt preferences.firstWeekdayInt
) )
else return StackWidget(context, id, StackWidgetType.FREQUENCY, habits) else StackWidget(context, id, StackWidgetType.FREQUENCY, habits)
} }
} }

@ -41,7 +41,7 @@ class HistoryWidget(
override val defaultHeight: Int = 250 override val defaultHeight: Int = 250
override val defaultWidth: Int = 250 override val defaultWidth: Int = 250
override fun getOnClickPendingIntent(context: Context): PendingIntent? { override fun getOnClickPendingIntent(context: Context): PendingIntent {
return pendingIntentFactory.showHabit(habit) return pendingIntentFactory.showHabit(habit)
} }

@ -23,11 +23,11 @@ import android.content.Context
class HistoryWidgetProvider : BaseWidgetProvider() { class HistoryWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget { override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id) val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return HistoryWidget( return if (habits.size == 1) HistoryWidget(
context, context,
id, id,
habits[0] habits[0]
) )
else return StackWidget(context, id, StackWidgetType.HISTORY, habits) else StackWidget(context, id, StackWidgetType.HISTORY, habits)
} }
} }

@ -36,7 +36,7 @@ class ScoreWidget(
override val defaultHeight: Int = 300 override val defaultHeight: Int = 300
override val defaultWidth: Int = 300 override val defaultWidth: Int = 300
override fun getOnClickPendingIntent(context: Context): PendingIntent? = override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit) pendingIntentFactory.showHabit(habit)
override fun refreshData(view: View) { override fun refreshData(view: View) {

@ -23,7 +23,7 @@ import android.content.Context
class ScoreWidgetProvider : BaseWidgetProvider() { class ScoreWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget { override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id) val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return ScoreWidget(context, id, habits[0]) return if (habits.size == 1) ScoreWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.SCORE, habits) else StackWidget(context, id, StackWidgetType.SCORE, habits)
} }
} }

@ -48,7 +48,10 @@ class StackWidgetService : RemoteViewsService() {
internal class StackRemoteViewsFactory(private val context: Context, intent: Intent) : internal class StackRemoteViewsFactory(private val context: Context, intent: Intent) :
RemoteViewsFactory { RemoteViewsFactory {
private val widgetId: Int private val widgetId: Int = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID
)
private val habitIds: LongArray private val habitIds: LongArray
private val widgetType: StackWidgetType? private val widgetType: StackWidgetType?
private var remoteViews = ArrayList<RemoteViews>() private var remoteViews = ArrayList<RemoteViews>()
@ -148,15 +151,11 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
} }
init { init {
widgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID
)
val widgetTypeValue = intent.getIntExtra(StackWidgetService.WIDGET_TYPE, -1) val widgetTypeValue = intent.getIntExtra(StackWidgetService.WIDGET_TYPE, -1)
val habitIdsStr = intent.getStringExtra(StackWidgetService.HABIT_IDS) val habitIdsStr = intent.getStringExtra(StackWidgetService.HABIT_IDS)
if (widgetTypeValue < 0) throw RuntimeException("invalid widget type") if (widgetTypeValue < 0) throw RuntimeException("invalid widget type")
if (habitIdsStr == null) throw RuntimeException("habitIdsStr is null") if (habitIdsStr == null) throw RuntimeException("habitIdsStr is null")
widgetType = StackWidgetType.Companion.getWidgetTypeFromValue(widgetTypeValue) widgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue)
habitIds = splitLongs(habitIdsStr) habitIds = splitLongs(habitIdsStr)
} }
} }

@ -37,7 +37,7 @@ class StreakWidget(
override val defaultHeight: Int = 200 override val defaultHeight: Int = 200
override val defaultWidth: Int = 200 override val defaultWidth: Int = 200
override fun getOnClickPendingIntent(context: Context): PendingIntent? = override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit) pendingIntentFactory.showHabit(habit)
override fun refreshData(view: View) { override fun refreshData(view: View) {

@ -23,7 +23,7 @@ import android.content.Context
class StreakWidgetProvider : BaseWidgetProvider() { class StreakWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget { override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id) val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return StreakWidget(context, id, habits[0]) return if (habits.size == 1) StreakWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.STREAKS, habits) else StackWidget(context, id, StackWidgetType.STREAKS, habits)
} }
} }

@ -40,7 +40,7 @@ class TargetWidget(
override val defaultHeight: Int = 200 override val defaultHeight: Int = 200
override val defaultWidth: Int = 200 override val defaultWidth: Int = 200
override fun getOnClickPendingIntent(context: Context): PendingIntent? = override fun getOnClickPendingIntent(context: Context): PendingIntent =
pendingIntentFactory.showHabit(habit) pendingIntentFactory.showHabit(habit)
override fun refreshData(view: View) = runBlocking { override fun refreshData(view: View) = runBlocking {

@ -23,7 +23,7 @@ import android.content.Context
class TargetWidgetProvider : BaseWidgetProvider() { class TargetWidgetProvider : BaseWidgetProvider() {
override fun getWidgetFromId(context: Context, id: Int): BaseWidget { override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
val habits = getHabitsFromWidgetId(id) val habits = getHabitsFromWidgetId(id)
if (habits.size == 1) return TargetWidget(context, id, habits[0]) return if (habits.size == 1) TargetWidget(context, id, habits[0])
else return StackWidget(context, id, StackWidgetType.TARGET, habits) else StackWidget(context, id, StackWidgetType.TARGET, habits)
} }
} }

@ -37,14 +37,15 @@ import org.isoron.uhabits.inject.HabitsApplicationComponent
import org.isoron.uhabits.utils.InterfaceUtils.getDimension import org.isoron.uhabits.utils.InterfaceUtils.getDimension
import org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor import org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import kotlin.math.min
class CheckmarkWidgetView : HabitWidgetView { class CheckmarkWidgetView : HabitWidgetView {
var activeColor: Int = 0 var activeColor: Int = 0
var percentage = 0f var percentage = 0f
var name: String? = null var name: String? = null
protected lateinit var ring: RingView private lateinit var ring: RingView
protected lateinit var label: TextView private lateinit var label: TextView
var entryValue = 0 var entryValue = 0
var entryState = 0 var entryState = 0
var isNumerical = false var isNumerical = false
@ -92,7 +93,7 @@ class CheckmarkWidgetView : HabitWidgetView {
postInvalidate() postInvalidate()
} }
protected val text: String private val text: String
get() = if (isNumerical) { get() = if (isNumerical) {
(entryValue / 1000.0).toShortString() (entryValue / 1000.0).toShortString()
} else when (entryState) { } else when (entryState) {
@ -122,7 +123,7 @@ class CheckmarkWidgetView : HabitWidgetView {
val height = MeasureSpec.getSize(heightMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec)
var w = width.toFloat() var w = width.toFloat()
var h = width * 1.25f var h = width * 1.25f
val scale = Math.min(width / w, height / h) val scale = min(width / w, height / h)
w *= scale w *= scale
h *= scale h *= scale
if (h < getDimension(context, R.dimen.checkmarkWidget_heightBreakpoint)) ring.visibility = if (h < getDimension(context, R.dimen.checkmarkWidget_heightBreakpoint)) ring.visibility =
@ -131,7 +132,7 @@ class CheckmarkWidgetView : HabitWidgetView {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(h.toInt(), MeasureSpec.EXACTLY) heightMeasureSpec = MeasureSpec.makeMeasureSpec(h.toInt(), MeasureSpec.EXACTLY)
var textSize = 0.15f * h var textSize = 0.15f * h
val maxTextSize = getDimension(context, R.dimen.smallerTextSize) val maxTextSize = getDimension(context, R.dimen.smallerTextSize)
textSize = Math.min(textSize, maxTextSize) textSize = min(textSize, maxTextSize)
label.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) label.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
ring.setTextSize(textSize) ring.setTextSize(textSize)
ring.setThickness(0.15f * textSize) ring.setThickness(0.15f * textSize)
@ -139,8 +140,7 @@ class CheckmarkWidgetView : HabitWidgetView {
} }
private fun init() { private fun init() {
val appComponent: HabitsApplicationComponent val appComponent: HabitsApplicationComponent = (context.applicationContext as HabitsApplication).component
appComponent = (context.applicationContext as HabitsApplication).component
preferences = appComponent.preferences preferences = appComponent.preferences
ring = findViewById<View>(R.id.scoreRing) as RingView ring = findViewById<View>(R.id.scoreRing) as RingView
label = findViewById<View>(R.id.label) as TextView label = findViewById<View>(R.id.label) as TextView

@ -32,6 +32,7 @@ import org.isoron.uhabits.R
import org.isoron.uhabits.utils.InterfaceUtils.dpToPixels import org.isoron.uhabits.utils.InterfaceUtils.dpToPixels
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import java.util.Arrays import java.util.Arrays
import kotlin.math.max
abstract class HabitWidgetView : FrameLayout { abstract class HabitWidgetView : FrameLayout {
protected var background: InsetDrawable? = null protected var background: InsetDrawable? = null
@ -73,7 +74,7 @@ abstract class HabitWidgetView : FrameLayout {
Arrays.fill(radii, cornerRadius) Arrays.fill(radii, cornerRadius)
val shape = RoundRectShape(radii, null, null) val shape = RoundRectShape(radii, null, null)
val innerDrawable = ShapeDrawable(shape) val innerDrawable = ShapeDrawable(shape)
val insetLeftTop = Math.max(shadowRadius - shadowOffset, 0) val insetLeftTop = max(shadowRadius - shadowOffset, 0)
val insetRightBottom = shadowRadius + shadowOffset val insetRightBottom = shadowRadius + shadowOffset
background = InsetDrawable( background = InsetDrawable(
innerDrawable, innerDrawable,

@ -18,6 +18,7 @@
*/ */
package org.isoron.uhabits package org.isoron.uhabits
import com.nhaarman.mockitokotlin2.spy
import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.memory.MemoryModelFactory import org.isoron.uhabits.core.models.memory.MemoryModelFactory
@ -29,7 +30,6 @@ import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnitRunner import org.mockito.junit.MockitoJUnitRunner
@RunWith(MockitoJUnitRunner::class) @RunWith(MockitoJUnitRunner::class)
@ -46,7 +46,7 @@ open class BaseAndroidJVMTest {
setFixedLocalTime(fixedLocalTime) setFixedLocalTime(fixedLocalTime)
setStartDayOffset(0, 0) setStartDayOffset(0, 0)
modelFactory = MemoryModelFactory() modelFactory = MemoryModelFactory()
habitList = Mockito.spy(modelFactory.buildHabitList()) habitList = spy(modelFactory.buildHabitList())
fixtures = HabitFixtures(modelFactory, habitList) fixtures = HabitFixtures(modelFactory, habitList)
taskRunner = SingleThreadTaskRunner() taskRunner = SingleThreadTaskRunner()
commandRunner = CommandRunner(taskRunner) commandRunner = CommandRunner(taskRunner)

@ -18,6 +18,9 @@
*/ */
package org.isoron.uhabits.receivers package org.isoron.uhabits.receivers
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
import org.isoron.uhabits.BaseAndroidJVMTest import org.isoron.uhabits.BaseAndroidJVMTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
@ -25,7 +28,6 @@ import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.reminders.ReminderScheduler import org.isoron.uhabits.core.reminders.ReminderScheduler
import org.isoron.uhabits.core.ui.NotificationTray import org.isoron.uhabits.core.ui.NotificationTray
import org.junit.Test import org.junit.Test
import org.mockito.Mockito
class ReminderControllerTest : BaseAndroidJVMTest() { class ReminderControllerTest : BaseAndroidJVMTest() {
private lateinit var controller: ReminderController private lateinit var controller: ReminderController
@ -34,9 +36,9 @@ class ReminderControllerTest : BaseAndroidJVMTest() {
private lateinit var preferences: Preferences private lateinit var preferences: Preferences
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
reminderScheduler = Mockito.mock(ReminderScheduler::class.java) reminderScheduler = mock()
notificationTray = Mockito.mock(NotificationTray::class.java) notificationTray = mock()
preferences = Mockito.mock(Preferences::class.java) preferences = mock()
controller = ReminderController( controller = ReminderController(
reminderScheduler, reminderScheduler,
notificationTray, notificationTray,
@ -47,24 +49,24 @@ class ReminderControllerTest : BaseAndroidJVMTest() {
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testOnDismiss() { fun testOnDismiss() {
Mockito.verifyNoMoreInteractions(reminderScheduler) verifyNoMoreInteractions(reminderScheduler)
Mockito.verifyNoMoreInteractions(notificationTray) verifyNoMoreInteractions(notificationTray)
Mockito.verifyNoMoreInteractions(preferences) verifyNoMoreInteractions(preferences)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testOnShowReminder() { fun testOnShowReminder() {
val habit = Mockito.mock(Habit::class.java) val habit: Habit = mock()
controller.onShowReminder(habit, Timestamp.ZERO.plus(100), 456) controller.onShowReminder(habit, Timestamp.ZERO.plus(100), 456)
Mockito.verify(notificationTray).show(habit, Timestamp.ZERO.plus(100), 456) verify(notificationTray).show(habit, Timestamp.ZERO.plus(100), 456)
Mockito.verify(reminderScheduler).scheduleAll() verify(reminderScheduler).scheduleAll()
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testOnBootCompleted() { fun testOnBootCompleted() {
controller.onBootCompleted() controller.onBootCompleted()
Mockito.verify(reminderScheduler).scheduleAll() verify(reminderScheduler).scheduleAll()
} }
} }

@ -55,10 +55,4 @@ class NumberButtonTest : BaseViewTest() {
val btn = NumberButton(theme.color(8), 99.0, 100.0, "steps", theme) val btn = NumberButton(theme.color(8), 99.0, 100.0, "steps", theme)
assertRenders(48, 48, "$base/render_below.png", btn) assertRenders(48, 48, "$base/render_below.png", btn)
} }
}
//@Test
fun testRenderZero() = asyncTest {
val btn = NumberButton(theme.color(8), 0.0, 100.0, "steps", theme)
assertRenders(48, 48, "$base/render_zero.png", btn)
}
}

@ -74,6 +74,7 @@ kotlin {
implementation 'nl.jqno.equalsverifier:equalsverifier:2.4.8' implementation 'nl.jqno.equalsverifier:equalsverifier:2.4.8'
implementation 'org.apache.commons:commons-io:1.3.2' implementation 'org.apache.commons:commons-io:1.3.2'
implementation 'org.mockito:mockito-core:2.28.2' implementation 'org.mockito:mockito-core:2.28.2'
implementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
} }
} }
} }

@ -51,7 +51,7 @@ interface Canvas {
fun fillCircle(centerX: Double, centerY: Double, radius: Double) fun fillCircle(centerX: Double, centerY: Double, radius: Double)
fun setTextAlign(align: TextAlign) fun setTextAlign(align: TextAlign)
fun toImage(): Image fun toImage(): Image
fun measureText(test: String): Double fun measureText(text: String): Double
/** /**
* Fills entire canvas with the current color. * Fills entire canvas with the current color.

@ -21,7 +21,7 @@ package org.isoron.platform.gui
class FontAwesome { class FontAwesome {
companion object { companion object {
val CHECK = "\uf00c" const val CHECK = "\uf00c"
val TIMES = "\uf00d" const val TIMES = "\uf00d"
} }
} }

@ -153,10 +153,10 @@ private fun daysSince2000(year: Int, month: Int, day: Int): Int {
result += ceil((year - 2000) / 4.0).toInt() result += ceil((year - 2000) / 4.0).toInt()
result -= ceil((year - 2000) / 100.0).toInt() result -= ceil((year - 2000) / 100.0).toInt()
result += ceil((year - 2000) / 400.0).toInt() result += ceil((year - 2000) / 400.0).toInt()
if (isLeapYear(year)) { result += if (isLeapYear(year)) {
result += leapOffset[month - 1] leapOffset[month - 1]
} else { } else {
result += nonLeapOffset[month - 1] nonLeapOffset[month - 1]
} }
result += (day - 1) result += (day - 1)
return result return result

@ -23,6 +23,7 @@ import kotlinx.coroutines.runBlocking
import org.isoron.platform.io.JavaFileOpener import org.isoron.platform.io.JavaFileOpener
import org.isoron.platform.io.JavaResourceFile import org.isoron.platform.io.JavaResourceFile
import java.awt.BasicStroke import java.awt.BasicStroke
import java.awt.Graphics2D
import java.awt.RenderingHints.KEY_ANTIALIASING import java.awt.RenderingHints.KEY_ANTIALIASING
import java.awt.RenderingHints.KEY_FRACTIONALMETRICS import java.awt.RenderingHints.KEY_FRACTIONALMETRICS
import java.awt.RenderingHints.KEY_TEXT_ANTIALIASING import java.awt.RenderingHints.KEY_TEXT_ANTIALIASING
@ -54,7 +55,7 @@ class JavaCanvas(
private var textAlign = TextAlign.CENTER private var textAlign = TextAlign.CENTER
val widthPx = image.width val widthPx = image.width
val heightPx = image.height val heightPx = image.height
val g2d = image.createGraphics() val g2d: Graphics2D = image.createGraphics()
private val NOTO_REGULAR_FONT = createFont("fonts/NotoSans-Regular.ttf") private val NOTO_REGULAR_FONT = createFont("fonts/NotoSans-Regular.ttf")
private val NOTO_BOLD_FONT = createFont("fonts/NotoSans-Bold.ttf") private val NOTO_BOLD_FONT = createFont("fonts/NotoSans-Bold.ttf")
@ -96,24 +97,28 @@ class JavaCanvas(
val bx = bounds.x.roundToInt() val bx = bounds.x.roundToInt()
val by = bounds.y.roundToInt() val by = bounds.y.roundToInt()
if (textAlign == TextAlign.CENTER) { when (textAlign) {
g2d.drawString( TextAlign.CENTER -> {
text, g2d.drawString(
toPixel(x) - bx - bWidth / 2, text,
toPixel(y) - by - bHeight / 2 toPixel(x) - bx - bWidth / 2,
) toPixel(y) - by - bHeight / 2
} else if (textAlign == TextAlign.LEFT) { )
g2d.drawString( }
text, TextAlign.LEFT -> {
toPixel(x) - bx, g2d.drawString(
toPixel(y) - by - bHeight / 2 text,
) toPixel(x) - bx,
} else { toPixel(y) - by - bHeight / 2
g2d.drawString( )
text, }
toPixel(x) - bx - bWidth, else -> {
toPixel(y) - by - bHeight / 2 g2d.drawString(
) text,
toPixel(x) - bx - bWidth,
toPixel(y) - by - bHeight / 2
)
}
} }
} }

@ -33,8 +33,8 @@ class JavaResourceFile(val path: String) : ResourceFile {
get() { get() {
val mainPath = Paths.get("assets/main/$path") val mainPath = Paths.get("assets/main/$path")
val testPath = Paths.get("assets/test/$path") val testPath = Paths.get("assets/test/$path")
if (Files.exists(mainPath)) return mainPath return if (Files.exists(mainPath)) mainPath
else return testPath else testPath
} }
override suspend fun exists(): Boolean { override suspend fun exists(): Boolean {

@ -71,7 +71,7 @@ object SQLParser {
val buffer = BufferedInputStream(stream) val buffer = BufferedInputStream(stream)
val commands: MutableList<String> = ArrayList() val commands: MutableList<String> = ArrayList()
val sb = StringBuffer() val sb = StringBuffer()
try { buffer.use { buffer ->
val tokenizer = Tokenizer(buffer) val tokenizer = Tokenizer(buffer)
var state = STATE_NONE var state = STATE_NONE
while (tokenizer.hasNext()) { while (tokenizer.hasNext()) {
@ -104,7 +104,7 @@ object SQLParser {
} }
if (state == STATE_NONE || state == STATE_STRING) { if (state == STATE_NONE || state == STATE_STRING) {
if (state == STATE_NONE && isWhitespace(c)) { if (state == STATE_NONE && isWhitespace(c)) {
if (sb.length > 0 && sb[sb.length - 1] != ' ') { if (sb.isNotEmpty() && sb[sb.length - 1] != ' ') {
sb.append(' ') sb.append(' ')
} }
} else { } else {
@ -112,8 +112,6 @@ object SQLParser {
} }
} }
} }
} finally {
buffer.close()
} }
if (sb.isNotEmpty()) { if (sb.isNotEmpty()) {
commands.add(sb.toString().trim { it <= ' ' }) commands.add(sb.toString().trim { it <= ' ' })

@ -37,6 +37,7 @@ import java.util.LinkedList
import java.util.Locale import java.util.Locale
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream import java.util.zip.ZipOutputStream
import kotlin.math.min
/** /**
* Class that exports the application data to CSV files. * Class that exports the application data to CSV files.
@ -77,7 +78,7 @@ class HabitsCSVExporter(
private fun sanitizeFilename(name: String): String { private fun sanitizeFilename(name: String): String {
val s = name.replace("[^ a-zA-Z0-9\\._-]+".toRegex(), "") val s = name.replace("[^ a-zA-Z0-9\\._-]+".toRegex(), "")
return s.substring(0, Math.min(s.length, 100)) return s.substring(0, min(s.length, 100))
} }
private fun writeHabits() { private fun writeHabits() {

@ -53,7 +53,7 @@ class LoopDBImporter
override fun canHandle(file: File): Boolean { override fun canHandle(file: File): Boolean {
if (!file.isSQLite3File()) return false if (!file.isSQLite3File()) return false
val db = opener.open(file)!! val db = opener.open(file)
var canHandle = true var canHandle = true
val c = db.query("select count(*) from SQLITE_MASTER where name='Habits' or name='Repetitions'") val c = db.query("select count(*) from SQLITE_MASTER where name='Habits' or name='Repetitions'")
if (!c.moveToNext() || c.getInt(0) != 2) { if (!c.moveToNext() || c.getInt(0) != 2) {
@ -70,7 +70,7 @@ class LoopDBImporter
} }
override fun importHabitsFromFile(file: File) { override fun importHabitsFromFile(file: File) {
val db = opener.open(file)!! val db = opener.open(file)
val helper = MigrationHelper(db) val helper = MigrationHelper(db)
helper.migrateTo(DATABASE_VERSION) helper.migrateTo(DATABASE_VERSION)

@ -156,15 +156,15 @@ open class EntryList {
get() = begin.daysUntil(end) + 1 get() = begin.daysUntil(end) + 1
} }
/**
* Converts a list of intervals into a list of entries. Entries that fall outside of any
* interval receive value UNKNOWN. Entries that fall within an interval but do not appear
* in [original] receive value YES_AUTO. Entries provided in [original] are copied over.
*
* The intervals should be sorted by timestamp. The first element in the list should
* correspond to the newest interval.
*/
companion object { companion object {
/**
* Converts a list of intervals into a list of entries. Entries that fall outside of any
* interval receive value UNKNOWN. Entries that fall within an interval but do not appear
* in [original] receive value YES_AUTO. Entries provided in [original] are copied over.
*
* The intervals should be sorted by timestamp. The first element in the list should
* correspond to the newest interval.
*/
fun buildEntriesFromInterval( fun buildEntriesFromInterval(
original: List<Entry>, original: List<Entry>,
intervals: List<Interval>, intervals: List<Interval>,

@ -31,13 +31,12 @@ interface ModelFactory {
fun buildHabit(): Habit { fun buildHabit(): Habit {
val scores = buildScoreList() val scores = buildScoreList()
val streaks = buildStreakList() val streaks = buildStreakList()
val habit = Habit( return Habit(
scores = scores, scores = scores,
streaks = streaks, streaks = streaks,
originalEntries = buildOriginalEntries(), originalEntries = buildOriginalEntries(),
computedEntries = buildComputedEntries(), computedEntries = buildComputedEntries(),
) )
return habit
} }
fun buildComputedEntries(): EntryList fun buildComputedEntries(): EntryList
fun buildOriginalEntries(): EntryList fun buildOriginalEntries(): EntryList

@ -18,6 +18,7 @@
*/ */
package org.isoron.uhabits.core.models package org.isoron.uhabits.core.models
import kotlin.math.pow
import kotlin.math.sqrt import kotlin.math.sqrt
data class Score( data class Score(
@ -40,7 +41,7 @@ data class Score(
previousScore: Double, previousScore: Double,
checkmarkValue: Double, checkmarkValue: Double,
): Double { ): Double {
val multiplier = Math.pow(0.5, sqrt(frequency) / 13.0) val multiplier = 0.5.pow(sqrt(frequency) / 13.0)
var score = previousScore * multiplier var score = previousScore * multiplier
score += checkmarkValue * (1 - multiplier) score += checkmarkValue * (1 - multiplier)
return score return score

@ -109,7 +109,7 @@ class ScoreList {
} }
} }
if (values[offset] != Entry.SKIP) { if (values[offset] != Entry.SKIP) {
val percentageCompleted = Math.min(1.0, rollingSum / numerator) val percentageCompleted = min(1.0, rollingSum / numerator)
previousValue = compute(freq, previousValue, percentageCompleted) previousValue = compute(freq, previousValue, percentageCompleted)
} }
} }

@ -47,7 +47,7 @@ class WeekdayList {
} }
fun toArray(): BooleanArray { fun toArray(): BooleanArray {
return Arrays.copyOf(weekdays, 7) return weekdays.copyOf(7)
} }
fun toInteger(): Int { fun toInteger(): Int {

@ -29,6 +29,8 @@ import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
import java.io.File import java.io.File
import java.util.Random import java.util.Random
import kotlin.math.max
import kotlin.math.min
class ShowHabitMenuPresenter( class ShowHabitMenuPresenter(
private val commandRunner: CommandRunner, private val commandRunner: CommandRunner,
@ -67,7 +69,7 @@ class ShowHabitMenuPresenter(
habit.originalEntries.clear() habit.originalEntries.clear()
var strength = 50.0 var strength = 50.0
for (i in 0 until 365 * 5) { for (i in 0 until 365 * 5) {
if (i % 7 == 0) strength = Math.max(0.0, Math.min(100.0, strength + 10 * random.nextGaussian())) if (i % 7 == 0) strength = max(0.0, min(100.0, strength + 10 * random.nextGaussian()))
if (random.nextInt(100) > strength) continue if (random.nextInt(100) > strength) continue
var value = Entry.YES_MANUAL var value = Entry.YES_MANUAL
if (habit.isNumerical) value = (1000 + 250 * random.nextGaussian() * strength / 100).toInt() * 1000 if (habit.isNumerical) value = (1000 + 250 * random.nextGaussian() * strength / 100).toInt() * 1000

@ -39,9 +39,9 @@ class OverviewCardPresenter {
val lastMonth = today.minus(30) val lastMonth = today.minus(30)
val lastYear = today.minus(365) val lastYear = today.minus(365)
val scores = habit.scores val scores = habit.scores
val scoreToday = scores.get(today).value.toFloat() val scoreToday = scores[today].value.toFloat()
val scoreLastMonth = scores.get(lastMonth).value.toFloat() val scoreLastMonth = scores[lastMonth].value.toFloat()
val scoreLastYear = scores.get(lastYear).value.toFloat() val scoreLastYear = scores[lastYear].value.toFloat()
val totalCount = habit.originalEntries.getKnown() val totalCount = habit.originalEntries.getKnown()
.filter { it.value == Entry.YES_MANUAL } .filter { it.value == Entry.YES_MANUAL }
.count() .count()

@ -39,13 +39,13 @@ class ScoreCardPresenter(
companion object { companion object {
val BUCKET_SIZES = intArrayOf(1, 7, 31, 92, 365) val BUCKET_SIZES = intArrayOf(1, 7, 31, 92, 365)
fun getTruncateField(bucketSize: Int): DateUtils.TruncateField { fun getTruncateField(bucketSize: Int): DateUtils.TruncateField {
when (bucketSize) { return when (bucketSize) {
1 -> return DateUtils.TruncateField.DAY 1 -> DateUtils.TruncateField.DAY
7 -> return DateUtils.TruncateField.WEEK_NUMBER 7 -> DateUtils.TruncateField.WEEK_NUMBER
31 -> return DateUtils.TruncateField.MONTH 31 -> DateUtils.TruncateField.MONTH
92 -> return DateUtils.TruncateField.QUARTER 92 -> DateUtils.TruncateField.QUARTER
365 -> return DateUtils.TruncateField.YEAR 365 -> DateUtils.TruncateField.YEAR
else -> return DateUtils.TruncateField.MONTH else -> DateUtils.TruncateField.MONTH
} }
} }

@ -63,7 +63,7 @@ class BarChart(
val nColumns = floor((safeWidth) / barGroupWidth).toInt() val nColumns = floor((safeWidth) / barGroupWidth).toInt()
val marginLeft = (safeWidth - nColumns * barGroupWidth) / 2 val marginLeft = (safeWidth - nColumns * barGroupWidth) / 2
val maxBarHeight = height - footerHeight - paddingTop val maxBarHeight = height - footerHeight - paddingTop
var maxValue = series.map { it.max()!! }.max()!! var maxValue = series.map { it.maxOrNull()!! }.maxOrNull()!!
maxValue = max(maxValue, 1.0) maxValue = max(maxValue, 1.0)
canvas.setColor(theme.cardBackgroundColor) canvas.setColor(theme.cardBackgroundColor)

@ -192,15 +192,15 @@ class HistoryChart(
val value = if (offset >= series.size) Square.OFF else series[offset] val value = if (offset >= series.size) Square.OFF else series[offset]
val squareColor: Color val squareColor: Color
val color = theme.color(paletteColor.paletteIndex) val color = theme.color(paletteColor.paletteIndex)
when (value) { squareColor = when (value) {
Square.ON -> { Square.ON -> {
squareColor = color color
} }
Square.OFF -> { Square.OFF -> {
squareColor = theme.lowContrastTextColor theme.lowContrastTextColor
} }
Square.DIMMED, Square.HATCHED -> { Square.DIMMED, Square.HATCHED -> {
squareColor = color.blendWith(theme.cardBackgroundColor, 0.5) color.blendWith(theme.cardBackgroundColor, 0.5)
} }
} }

@ -76,7 +76,7 @@ abstract class DateUtils {
if (fixedLocalTime != null) return fixedLocalTime as Long if (fixedLocalTime != null) return fixedLocalTime as Long
val tz = getTimeZone() val tz = getTimeZone()
val now = Date().getTime() val now = Date().time
return now + tz.getOffset(now) return now + tz.getOffset(now)
} }

@ -37,7 +37,7 @@ open class MidnightTimer @Inject constructor() {
this.listeners.add(listener) this.listeners.add(listener)
} }
@Synchronized fun onPause() = executor.shutdownNow() @Synchronized fun onPause(): MutableList<Runnable>? = executor.shutdownNow()
@Synchronized fun onResume() { @Synchronized fun onResume() {
executor = Executors.newSingleThreadScheduledExecutor() executor = Executors.newSingleThreadScheduledExecutor()

@ -59,11 +59,10 @@ class StringUtils {
@JvmStatic @JvmStatic
fun splitLongs(str: String): LongArray { fun splitLongs(str: String): LongArray {
val parts: Array<String> = org.apache.commons.lang3.StringUtils.split(str, ',') val parts: Array<String> = org.apache.commons.lang3.StringUtils.split(str, ',')
val numbers = LongArray(parts.size) { return LongArray(parts.size) {
i -> i ->
parts[i].toLong() parts[i].toLong()
} }
return numbers
} }
} }
} }

@ -18,6 +18,8 @@
*/ */
package org.isoron.uhabits.core package org.isoron.uhabits.core
import com.nhaarman.mockitokotlin2.spy
import com.nhaarman.mockitokotlin2.validateMockitoUsage
import org.apache.commons.io.IOUtils import org.apache.commons.io.IOUtils
import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.database.Database import org.isoron.uhabits.core.database.Database
@ -37,7 +39,6 @@ import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnitRunner import org.mockito.junit.MockitoJUnitRunner
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
@ -78,7 +79,7 @@ open class BaseUnitTest {
setFixedLocalTime(FIXED_LOCAL_TIME) setFixedLocalTime(FIXED_LOCAL_TIME)
setStartDayOffset(0, 0) setStartDayOffset(0, 0)
val memoryModelFactory = MemoryModelFactory() val memoryModelFactory = MemoryModelFactory()
habitList = Mockito.spy(memoryModelFactory.buildHabitList()) habitList = spy(memoryModelFactory.buildHabitList())
fixtures = HabitFixtures(memoryModelFactory, habitList) fixtures = HabitFixtures(memoryModelFactory, habitList)
modelFactory = memoryModelFactory modelFactory = memoryModelFactory
taskRunner = SingleThreadTaskRunner() taskRunner = SingleThreadTaskRunner()
@ -88,7 +89,7 @@ open class BaseUnitTest {
@After @After
@Throws(Exception::class) @Throws(Exception::class)
open fun tearDown() { open fun tearDown() {
Mockito.validateMockitoUsage() validateMockitoUsage()
setFixedLocalTime(null) setFixedLocalTime(null)
setStartDayOffset(0, 0) setStartDayOffset(0, 0)
} }

@ -26,21 +26,21 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
class ArchiveHabitsCommandTest : BaseUnitTest() { class ArchiveHabitsCommandTest : BaseUnitTest() {
private var command: ArchiveHabitsCommand? = null private lateinit var command: ArchiveHabitsCommand
private var habit: Habit? = null private lateinit var habit: Habit
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
habit = fixtures.createShortHabit() habit = fixtures.createShortHabit()
habitList.add(habit!!) habitList.add(habit)
command = ArchiveHabitsCommand(habitList, listOf(habit!!)) command = ArchiveHabitsCommand(habitList, listOf(habit))
} }
@Test @Test
fun testExecute() { fun testExecute() {
assertFalse(habit!!.isArchived) assertFalse(habit.isArchived)
command!!.run() command.run()
assertTrue(habit!!.isArchived) assertTrue(habit.isArchived)
} }
} }

@ -18,7 +18,7 @@
*/ */
package org.isoron.uhabits.core.commands package org.isoron.uhabits.core.commands
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@ -54,16 +54,13 @@ class ChangeHabitColorCommandTest : BaseUnitTest() {
private fun checkNewColors() { private fun checkNewColors() {
for (habit in selected) { for (habit in selected) {
assertThat(habit.color, CoreMatchers.equalTo(PaletteColor(0))) assertThat(habit.color, equalTo(PaletteColor(0)))
} }
} }
private fun checkOriginalColors() { private fun checkOriginalColors() {
var k = 0 var k = 0
for (habit in selected) for (habit in selected)
assertThat( assertThat(habit.color, equalTo(PaletteColor(++k)))
habit.color,
CoreMatchers.equalTo(PaletteColor(++k))
)
} }
} }

@ -19,7 +19,7 @@
package org.isoron.uhabits.core.commands package org.isoron.uhabits.core.commands
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@ -46,13 +46,8 @@ class CreateHabitCommandTest : BaseUnitTest() {
fun testExecute() { fun testExecute() {
assertTrue(habitList.isEmpty) assertTrue(habitList.isEmpty)
command.run() command.run()
assertThat(habitList.size(), CoreMatchers.equalTo(1)) assertThat(habitList.size(), equalTo(1))
val habit = habitList.getByPosition(0) val habit = habitList.getByPosition(0)
assertThat( assertThat(habit.name, equalTo(model.name))
habit.name,
CoreMatchers.equalTo(
model.name
)
)
} }
} }

@ -28,26 +28,26 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
class CreateRepetitionCommandTest : BaseUnitTest() { class CreateRepetitionCommandTest : BaseUnitTest() {
private var command: CreateRepetitionCommand? = null private lateinit var command: CreateRepetitionCommand
private var habit: Habit? = null private lateinit var habit: Habit
private var today: Timestamp? = null private lateinit var today: Timestamp
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
habit = fixtures.createShortHabit() habit = fixtures.createShortHabit()
habitList.add(habit!!) habitList.add(habit)
today = getToday() today = getToday()
command = CreateRepetitionCommand(habitList, habit!!, today!!, 100) command = CreateRepetitionCommand(habitList, habit, today, 100)
} }
@Test @Test
fun testExecute() { fun testExecute() {
val entries = habit!!.originalEntries val entries = habit.originalEntries
var entry = entries.get(today!!) var entry = entries.get(today)
assertEquals(Entry.YES_MANUAL, entry.value) assertEquals(Entry.YES_MANUAL, entry.value)
command!!.run() command.run()
entry = entries.get(today!!) entry = entries.get(today)
assertEquals(100, entry.value.toLong()) assertEquals(100, entry.value.toLong())
} }
} }

@ -18,7 +18,7 @@
*/ */
package org.isoron.uhabits.core.commands package org.isoron.uhabits.core.commands
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@ -34,6 +34,7 @@ class DeleteHabitsCommandTest : BaseUnitTest() {
@get:Rule @get:Rule
var thrown = ExpectedException.none()!! var thrown = ExpectedException.none()!!
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
@ -56,9 +57,9 @@ class DeleteHabitsCommandTest : BaseUnitTest() {
@Test @Test
fun testExecute() { fun testExecute() {
assertThat(habitList.size(), CoreMatchers.equalTo(4)) assertThat(habitList.size(), equalTo(4))
command.run() command.run()
assertThat(habitList.size(), CoreMatchers.equalTo(1)) assertThat(habitList.size(), equalTo(1))
assertThat(habitList.getByPosition(0).name, CoreMatchers.equalTo("extra")) assertThat(habitList.getByPosition(0).name, equalTo("extra"))
} }
} }

@ -36,6 +36,7 @@ class Version22Test : BaseUnitTest() {
var exception = ExpectedException.none()!! var exception = ExpectedException.none()!!
private lateinit var db: Database private lateinit var db: Database
private lateinit var helper: MigrationHelper private lateinit var helper: MigrationHelper
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
@ -49,48 +50,25 @@ class Version22Test : BaseUnitTest() {
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testKeepValidReps() { fun testKeepValidReps() {
db.query( db.query("select count(*) from repetitions") { c: Cursor ->
"select count(*) from repetitions" assertThat(c.getInt(0), equalTo(3))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(3)
)
} }
helper.migrateTo(22) helper.migrateTo(22)
db.query( db.query("select count(*) from repetitions") { c: Cursor ->
"select count(*) from repetitions" assertThat(c.getInt(0), equalTo(3))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(3)
)
} }
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testRemoveRepsWithInvalidId() { fun testRemoveRepsWithInvalidId() {
db.execute( db.execute("insert into Repetitions(habit, timestamp, value) values (99999, 100, 2)")
"insert into Repetitions(habit, timestamp, value) " + db.query("select count(*) from repetitions where habit = 99999") { c: Cursor ->
"values (99999, 100, 2)" assertThat(c.getInt(0), equalTo(1))
)
db.query(
"select count(*) from repetitions where habit = 99999"
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(1)
)
} }
helper.migrateTo(22) helper.migrateTo(22)
db.query( db.query("select count(*) from repetitions where habit = 99999") { c: Cursor ->
"select count(*) from repetitions where habit = 99999" assertThat(c.getInt(0), equalTo(0))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(0)
)
} }
} }
@ -99,32 +77,19 @@ class Version22Test : BaseUnitTest() {
fun testDisallowNewRepsWithInvalidRef() { fun testDisallowNewRepsWithInvalidRef() {
helper.migrateTo(22) helper.migrateTo(22)
exception.expectMessage(Matchers.containsString("SQLITE_CONSTRAINT")) exception.expectMessage(Matchers.containsString("SQLITE_CONSTRAINT"))
db.execute( db.execute("insert into Repetitions(habit, timestamp, value) values (99999, 100, 2)")
"insert into Repetitions(habit, timestamp, value) " +
"values (99999, 100, 2)"
)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testRemoveRepetitionsWithNullTimestamp() { fun testRemoveRepetitionsWithNullTimestamp() {
db.execute("insert into repetitions(habit, value) values (0, 2)") db.execute("insert into repetitions(habit, value) values (0, 2)")
db.query( db.query("select count(*) from repetitions where timestamp is null") { c: Cursor ->
"select count(*) from repetitions where timestamp is null" assertThat(c.getInt(0), equalTo(1))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(1)
)
} }
helper.migrateTo(22) helper.migrateTo(22)
db.query( db.query("select count(*) from repetitions where timestamp is null") { c: Cursor ->
"select count(*) from repetitions where timestamp is null" assertThat(c.getInt(0), equalTo(0))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(0)
)
} }
} }
@ -140,22 +105,12 @@ class Version22Test : BaseUnitTest() {
@Throws(Exception::class) @Throws(Exception::class)
fun testRemoveRepetitionsWithNullHabit() { fun testRemoveRepetitionsWithNullHabit() {
db.execute("insert into repetitions(timestamp, value) values (0, 2)") db.execute("insert into repetitions(timestamp, value) values (0, 2)")
db.query( db.query("select count(*) from repetitions where habit is null") { c: Cursor ->
"select count(*) from repetitions where habit is null" assertThat(c.getInt(0), equalTo(1))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(1)
)
} }
helper.migrateTo(22) helper.migrateTo(22)
db.query( db.query("select count(*) from repetitions where habit is null") { c: Cursor ->
"select count(*) from repetitions where habit is null" assertThat(c.getInt(0), equalTo(0))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(0)
)
} }
} }
@ -164,42 +119,21 @@ class Version22Test : BaseUnitTest() {
fun testDisallowNullHabit() { fun testDisallowNullHabit() {
helper.migrateTo(22) helper.migrateTo(22)
exception.expectMessage(Matchers.containsString("SQLITE_CONSTRAINT")) exception.expectMessage(Matchers.containsString("SQLITE_CONSTRAINT"))
db.execute( db.execute("insert into Repetitions(timestamp, value) " + "values (5, 2)")
"insert into Repetitions(timestamp, value) " + "values (5, 2)"
)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testRemoveDuplicateRepetitions() { fun testRemoveDuplicateRepetitions() {
db.execute( db.execute("insert into repetitions(habit, timestamp, value)values (0, 100, 2)")
"insert into repetitions(habit, timestamp, value)" + db.execute("insert into repetitions(habit, timestamp, value)values (0, 100, 5)")
"values (0, 100, 2)" db.execute("insert into repetitions(habit, timestamp, value)values (0, 100, 10)")
) db.query("select count(*) from repetitions where timestamp=100 and habit=0") { c: Cursor ->
db.execute( assertThat(c.getInt(0), equalTo(3))
"insert into repetitions(habit, timestamp, value)" +
"values (0, 100, 5)"
)
db.execute(
"insert into repetitions(habit, timestamp, value)" +
"values (0, 100, 10)"
)
db.query(
"select count(*) from repetitions where timestamp=100 and habit=0"
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(3)
)
} }
helper.migrateTo(22) helper.migrateTo(22)
db.query( db.query("select count(*) from repetitions where timestamp=100 and habit=0") { c: Cursor ->
"select count(*) from repetitions where timestamp=100 and habit=0" assertThat(c.getInt(0), equalTo(1))
) { c: Cursor ->
assertThat(
c.getInt(0),
equalTo(1)
)
} }
} }
@ -207,14 +141,8 @@ class Version22Test : BaseUnitTest() {
@Throws(Exception::class) @Throws(Exception::class)
fun testDisallowNewDuplicateTimestamps() { fun testDisallowNewDuplicateTimestamps() {
helper.migrateTo(22) helper.migrateTo(22)
db.execute( db.execute("insert into repetitions(habit, timestamp, value)values (0, 100, 2)")
"insert into repetitions(habit, timestamp, value)" +
"values (0, 100, 2)"
)
exception.expectMessage(Matchers.containsString("SQLITE_CONSTRAINT")) exception.expectMessage(Matchers.containsString("SQLITE_CONSTRAINT"))
db.execute( db.execute("insert into repetitions(habit, timestamp, value)values (0, 100, 5)")
"insert into repetitions(habit, timestamp, value)" +
"values (0, 100, 5)"
)
} }
} }

@ -18,7 +18,6 @@
*/ */
package org.isoron.uhabits.core.io package org.isoron.uhabits.core.io
import junit.framework.Assert.assertNotNull
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import org.apache.commons.io.IOUtils import org.apache.commons.io.IOUtils
@ -34,7 +33,7 @@ import java.util.LinkedList
import java.util.zip.ZipFile import java.util.zip.ZipFile
class HabitsCSVExporterTest : BaseUnitTest() { class HabitsCSVExporterTest : BaseUnitTest() {
private var baseDir: File? = null private lateinit var baseDir: File
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
@ -42,7 +41,6 @@ class HabitsCSVExporterTest : BaseUnitTest() {
habitList.add(fixtures.createShortHabit()) habitList.add(fixtures.createShortHabit())
habitList.add(fixtures.createEmptyHabit()) habitList.add(fixtures.createEmptyHabit())
baseDir = Files.createTempDirectory("csv").toFile() baseDir = Files.createTempDirectory("csv").toFile()
assertNotNull(baseDir)
} }
@Throws(Exception::class) @Throws(Exception::class)
@ -59,7 +57,7 @@ class HabitsCSVExporterTest : BaseUnitTest() {
val exporter = HabitsCSVExporter( val exporter = HabitsCSVExporter(
habitList, habitList,
selected, selected,
baseDir!! baseDir
) )
val filename = exporter.writeArchive() val filename = exporter.writeArchive()
assertAbsolutePathExists(filename) assertAbsolutePathExists(filename)
@ -84,7 +82,7 @@ class HabitsCSVExporterTest : BaseUnitTest() {
val stream = zip.getInputStream(entry) val stream = zip.getInputStream(entry)
val outputFilename = String.format( val outputFilename = String.format(
"%s/%s", "%s/%s",
baseDir!!.absolutePath, baseDir.absolutePath,
entry.name entry.name
) )
val out = File(outputFilename) val out = File(outputFilename)
@ -96,7 +94,7 @@ class HabitsCSVExporterTest : BaseUnitTest() {
} }
private fun assertPathExists(s: String) { private fun assertPathExists(s: String) {
assertAbsolutePathExists(String.format("%s/%s", baseDir!!.absolutePath, s)) assertAbsolutePathExists(String.format("%s/%s", baseDir.absolutePath, s))
} }
private fun assertAbsolutePathExists(s: String) { private fun assertAbsolutePathExists(s: String) {

@ -21,7 +21,7 @@ package org.isoron.uhabits.core.io
import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual import org.hamcrest.core.IsEqual.equalTo
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.Frequency
@ -46,11 +46,11 @@ class ImportTest : BaseUnitTest() {
@Throws(IOException::class) @Throws(IOException::class)
fun testHabitBullCSV() { fun testHabitBullCSV() {
importFromFile("habitbull.csv") importFromFile("habitbull.csv")
assertThat(habitList.size(), IsEqual.equalTo(4)) assertThat(habitList.size(), equalTo(4))
val habit = habitList.getByPosition(0) val habit = habitList.getByPosition(0)
assertThat(habit.name, IsEqual.equalTo("Breed dragons")) assertThat(habit.name, equalTo("Breed dragons"))
assertThat(habit.description, IsEqual.equalTo("with love and fire")) assertThat(habit.description, equalTo("with love and fire"))
assertThat(habit.frequency, IsEqual.equalTo(Frequency.DAILY)) assertThat(habit.frequency, equalTo(Frequency.DAILY))
assertTrue(isChecked(habit, 2016, 3, 18)) assertTrue(isChecked(habit, 2016, 3, 18))
assertTrue(isChecked(habit, 2016, 3, 19)) assertTrue(isChecked(habit, 2016, 3, 19))
assertFalse(isChecked(habit, 2016, 3, 20)) assertFalse(isChecked(habit, 2016, 3, 20))
@ -60,10 +60,10 @@ class ImportTest : BaseUnitTest() {
@Throws(IOException::class) @Throws(IOException::class)
fun testLoopDB() { fun testLoopDB() {
importFromFile("loop.db") importFromFile("loop.db")
assertThat(habitList.size(), IsEqual.equalTo(9)) assertThat(habitList.size(), equalTo(9))
val habit = habitList.getByPosition(0) val habit = habitList.getByPosition(0)
assertThat(habit.name, IsEqual.equalTo("Wake up early")) assertThat(habit.name, equalTo("Wake up early"))
assertThat(habit.frequency, IsEqual.equalTo(Frequency.THREE_TIMES_PER_WEEK)) assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK))
assertTrue(isChecked(habit, 2016, 3, 14)) assertTrue(isChecked(habit, 2016, 3, 14))
assertTrue(isChecked(habit, 2016, 3, 16)) assertTrue(isChecked(habit, 2016, 3, 16))
assertFalse(isChecked(habit, 2016, 3, 17)) assertFalse(isChecked(habit, 2016, 3, 17))
@ -73,33 +73,33 @@ class ImportTest : BaseUnitTest() {
@Throws(IOException::class) @Throws(IOException::class)
fun testRewireDB() { fun testRewireDB() {
importFromFile("rewire.db") importFromFile("rewire.db")
assertThat(habitList.size(), IsEqual.equalTo(3)) assertThat(habitList.size(), equalTo(3))
var habit = habitList.getByPosition(1) var habit = habitList.getByPosition(1)
assertThat(habit.name, IsEqual.equalTo("Wake up early")) assertThat(habit.name, equalTo("Wake up early"))
assertThat(habit.frequency, IsEqual.equalTo(Frequency.THREE_TIMES_PER_WEEK)) assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK))
assertFalse(habit.hasReminder()) assertFalse(habit.hasReminder())
assertFalse(isChecked(habit, 2015, 12, 31)) assertFalse(isChecked(habit, 2015, 12, 31))
assertTrue(isChecked(habit, 2016, 1, 18)) assertTrue(isChecked(habit, 2016, 1, 18))
assertTrue(isChecked(habit, 2016, 1, 28)) assertTrue(isChecked(habit, 2016, 1, 28))
assertFalse(isChecked(habit, 2016, 3, 10)) assertFalse(isChecked(habit, 2016, 3, 10))
habit = habitList.getByPosition(2) habit = habitList.getByPosition(2)
assertThat(habit.name, IsEqual.equalTo("brush teeth")) assertThat(habit.name, equalTo("brush teeth"))
assertThat(habit.frequency, IsEqual.equalTo(Frequency.THREE_TIMES_PER_WEEK)) assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK))
assertThat(habit.hasReminder(), IsEqual.equalTo(true)) assertThat(habit.hasReminder(), equalTo(true))
val reminder = habit.reminder val reminder = habit.reminder
assertThat(reminder!!.hour, IsEqual.equalTo(8)) assertThat(reminder!!.hour, equalTo(8))
assertThat(reminder.minute, IsEqual.equalTo(0)) assertThat(reminder.minute, equalTo(0))
val reminderDays = booleanArrayOf(false, true, true, true, true, true, false) val reminderDays = booleanArrayOf(false, true, true, true, true, true, false)
assertThat(reminder.days.toArray(), IsEqual.equalTo(reminderDays)) assertThat(reminder.days.toArray(), equalTo(reminderDays))
} }
@Test @Test
@Throws(IOException::class) @Throws(IOException::class)
fun testTickmateDB() { fun testTickmateDB() {
importFromFile("tickmate.db") importFromFile("tickmate.db")
assertThat(habitList.size(), IsEqual.equalTo(3)) assertThat(habitList.size(), equalTo(3))
val h = habitList.getByPosition(2) val h = habitList.getByPosition(2)
assertThat(h.name, IsEqual.equalTo("Vegan")) assertThat(h.name, equalTo("Vegan"))
assertTrue(isChecked(h, 2016, 1, 24)) assertTrue(isChecked(h, 2016, 1, 24))
assertTrue(isChecked(h, 2016, 2, 5)) assertTrue(isChecked(h, 2016, 2, 5))
assertTrue(isChecked(h, 2016, 3, 18)) assertTrue(isChecked(h, 2016, 3, 18))

@ -19,10 +19,10 @@
package org.isoron.uhabits.core.models package org.isoron.uhabits.core.models
import junit.framework.Assert.assertEquals import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertNotNull import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertNull import junit.framework.Assert.assertNull
import junit.framework.TestCase import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.not
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.junit.Rule import org.junit.Rule
@ -64,48 +64,25 @@ class HabitListTest : BaseUnitTest() {
@Test @Test
fun testSize() { fun testSize() {
assertThat(habitList.size(), CoreMatchers.equalTo(10)) assertThat(habitList.size(), equalTo(10))
assertThat(activeHabits.size(), CoreMatchers.equalTo(6)) assertThat(activeHabits.size(), equalTo(6))
assertThat(reminderHabits.size(), CoreMatchers.equalTo(4)) assertThat(reminderHabits.size(), equalTo(4))
} }
@Test @Test
fun testGetByPosition() { fun testGetByPosition() {
assertThat( assertThat(habitList.getByPosition(0), equalTo(habitsArray[0]))
habitList.getByPosition(0), assertThat(habitList.getByPosition(3), equalTo(habitsArray[3]))
CoreMatchers.equalTo( assertThat(habitList.getByPosition(9), equalTo(habitsArray[9]))
habitsArray[0] assertThat(activeHabits.getByPosition(0), equalTo(habitsArray[2]))
) assertThat(reminderHabits.getByPosition(1), equalTo(habitsArray[3]))
)
assertThat(
habitList.getByPosition(3),
CoreMatchers.equalTo(
habitsArray[3]
)
)
assertThat(
habitList.getByPosition(9),
CoreMatchers.equalTo(
habitsArray[9]
)
)
assertThat(
activeHabits.getByPosition(0),
CoreMatchers.equalTo(
habitsArray[2]
)
)
assertThat(
reminderHabits.getByPosition(1),
CoreMatchers.equalTo(habitsArray[3])
)
} }
@Test @Test
fun testGetById() { fun testGetById() {
val habit1 = habitsArray[0] val habit1 = habitsArray[0]
val habit2 = habitList.getById(habit1.id!!) val habit2 = habitList.getById(habit1.id!!)
assertThat(habit1, CoreMatchers.equalTo(habit2)) assertThat(habit1, equalTo(habit2))
} }
@Test @Test
@ -128,41 +105,41 @@ class HabitListTest : BaseUnitTest() {
} }
list.primaryOrder = HabitList.Order.BY_POSITION list.primaryOrder = HabitList.Order.BY_POSITION
assertThat(list.getByPosition(0), CoreMatchers.equalTo(h3)) assertThat(list.getByPosition(0), equalTo(h3))
assertThat(list.getByPosition(1), CoreMatchers.equalTo(h1)) assertThat(list.getByPosition(1), equalTo(h1))
assertThat(list.getByPosition(2), CoreMatchers.equalTo(h4)) assertThat(list.getByPosition(2), equalTo(h4))
assertThat(list.getByPosition(3), CoreMatchers.equalTo(h2)) assertThat(list.getByPosition(3), equalTo(h2))
list.primaryOrder = HabitList.Order.BY_NAME_DESC list.primaryOrder = HabitList.Order.BY_NAME_DESC
assertThat(list.getByPosition(0), CoreMatchers.equalTo(h4)) assertThat(list.getByPosition(0), equalTo(h4))
assertThat(list.getByPosition(1), CoreMatchers.equalTo(h3)) assertThat(list.getByPosition(1), equalTo(h3))
assertThat(list.getByPosition(2), CoreMatchers.equalTo(h2)) assertThat(list.getByPosition(2), equalTo(h2))
assertThat(list.getByPosition(3), CoreMatchers.equalTo(h1)) assertThat(list.getByPosition(3), equalTo(h1))
list.primaryOrder = HabitList.Order.BY_NAME_ASC list.primaryOrder = HabitList.Order.BY_NAME_ASC
assertThat(list.getByPosition(0), CoreMatchers.equalTo(h1)) assertThat(list.getByPosition(0), equalTo(h1))
assertThat(list.getByPosition(1), CoreMatchers.equalTo(h2)) assertThat(list.getByPosition(1), equalTo(h2))
assertThat(list.getByPosition(2), CoreMatchers.equalTo(h3)) assertThat(list.getByPosition(2), equalTo(h3))
assertThat(list.getByPosition(3), CoreMatchers.equalTo(h4)) assertThat(list.getByPosition(3), equalTo(h4))
list.primaryOrder = HabitList.Order.BY_NAME_ASC list.primaryOrder = HabitList.Order.BY_NAME_ASC
list.remove(h1) list.remove(h1)
list.add(h1) list.add(h1)
assertThat(list.getByPosition(0), CoreMatchers.equalTo(h1)) assertThat(list.getByPosition(0), equalTo(h1))
list.primaryOrder = HabitList.Order.BY_COLOR_ASC list.primaryOrder = HabitList.Order.BY_COLOR_ASC
list.secondaryOrder = HabitList.Order.BY_NAME_ASC list.secondaryOrder = HabitList.Order.BY_NAME_ASC
assertThat(list.getByPosition(0), CoreMatchers.equalTo(h3)) assertThat(list.getByPosition(0), equalTo(h3))
assertThat(list.getByPosition(1), CoreMatchers.equalTo(h4)) assertThat(list.getByPosition(1), equalTo(h4))
assertThat(list.getByPosition(2), CoreMatchers.equalTo(h1)) assertThat(list.getByPosition(2), equalTo(h1))
assertThat(list.getByPosition(3), CoreMatchers.equalTo(h2)) assertThat(list.getByPosition(3), equalTo(h2))
list.primaryOrder = HabitList.Order.BY_COLOR_DESC list.primaryOrder = HabitList.Order.BY_COLOR_DESC
list.secondaryOrder = HabitList.Order.BY_NAME_ASC list.secondaryOrder = HabitList.Order.BY_NAME_ASC
assertThat(list.getByPosition(0), CoreMatchers.equalTo(h1)) assertThat(list.getByPosition(0), equalTo(h1))
assertThat(list.getByPosition(1), CoreMatchers.equalTo(h2)) assertThat(list.getByPosition(1), equalTo(h2))
assertThat(list.getByPosition(2), CoreMatchers.equalTo(h4)) assertThat(list.getByPosition(2), equalTo(h4))
assertThat(list.getByPosition(3), CoreMatchers.equalTo(h3)) assertThat(list.getByPosition(3), equalTo(h3))
list.primaryOrder = HabitList.Order.BY_POSITION list.primaryOrder = HabitList.Order.BY_POSITION
assertThat(list.getByPosition(0), CoreMatchers.equalTo(h3)) assertThat(list.getByPosition(0), equalTo(h3))
assertThat(list.getByPosition(1), CoreMatchers.equalTo(h1)) assertThat(list.getByPosition(1), equalTo(h1))
assertThat(list.getByPosition(2), CoreMatchers.equalTo(h4)) assertThat(list.getByPosition(2), equalTo(h4))
assertThat(list.getByPosition(3), CoreMatchers.equalTo(h2)) assertThat(list.getByPosition(3), equalTo(h2))
} }
@Test @Test
@ -182,18 +159,13 @@ class HabitListTest : BaseUnitTest() {
val actualSequence = IntArray(10) val actualSequence = IntArray(10)
for (j in 0..9) { for (j in 0..9) {
val habit = habitList.getByPosition(j) val habit = habitList.getByPosition(j)
assertThat(habit.position, CoreMatchers.equalTo(j)) assertThat(habit.position, equalTo(j))
actualSequence[j] = Math.toIntExact(habit.id!!) actualSequence[j] = Math.toIntExact(habit.id!!)
} }
assertThat( assertThat(actualSequence, equalTo(expectedSequence[i]))
actualSequence,
CoreMatchers.equalTo(
expectedSequence[i]
)
)
} }
assertThat(activeHabits.indexOf(habitsArray[5]), CoreMatchers.equalTo(0)) assertThat(activeHabits.indexOf(habitsArray[5]), equalTo(0))
assertThat(activeHabits.indexOf(habitsArray[2]), CoreMatchers.equalTo(1)) assertThat(activeHabits.indexOf(habitsArray[2]), equalTo(1))
} }
@Test @Test
@ -244,26 +216,20 @@ class HabitListTest : BaseUnitTest() {
""".trimIndent() """.trimIndent()
val writer = StringWriter() val writer = StringWriter()
list.writeCSV(writer) list.writeCSV(writer)
assertThat(writer.toString(), CoreMatchers.equalTo(expectedCSV)) assertThat(writer.toString(), equalTo(expectedCSV))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testAdd() { fun testAdd() {
val h1 = fixtures.createEmptyHabit() val h1 = fixtures.createEmptyHabit()
TestCase.assertFalse(h1.isArchived) assertFalse(h1.isArchived)
assertNull(h1.id) assertNull(h1.id)
assertThat(habitList.indexOf(h1), CoreMatchers.equalTo(-1)) assertThat(habitList.indexOf(h1), equalTo(-1))
habitList.add(h1) habitList.add(h1)
assertNotNull(h1.id) h1.id!!
assertThat( assertThat(habitList.indexOf(h1), not(equalTo(-1)))
habitList.indexOf(h1), assertThat(activeHabits.indexOf(h1), not(equalTo(-1)))
CoreMatchers.not(CoreMatchers.equalTo(-1))
)
assertThat(
activeHabits.indexOf(h1),
CoreMatchers.not(CoreMatchers.equalTo(-1))
)
} }
@Test @Test

@ -19,9 +19,9 @@
package org.isoron.uhabits.core.models package org.isoron.uhabits.core.models
import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertNotNull
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.core.IsEqual.equalTo
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday
import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotEquals
@ -41,11 +41,9 @@ class HabitTest : BaseUnitTest() {
@Test @Test
fun testUuidGeneration() { fun testUuidGeneration() {
val (_, _, _, _, _, _, _, _, _, _, _, _, _, uuid) = modelFactory.buildHabit() val uuid1 = modelFactory.buildHabit().uuid!!
val (_, _, _, _, _, _, _, _, _, _, _, _, _, uuid1) = modelFactory.buildHabit() val uuid2 = modelFactory.buildHabit().uuid!!
assertNotNull(uuid) assertNotEquals(uuid1, uuid2)
assertNotNull(uuid1)
assertNotEquals(uuid, uuid1)
} }
@Test @Test
@ -57,18 +55,19 @@ class HabitTest : BaseUnitTest() {
model.reminder = Reminder(8, 30, WeekdayList(1)) model.reminder = Reminder(8, 30, WeekdayList(1))
val habit = modelFactory.buildHabit() val habit = modelFactory.buildHabit()
habit.copyFrom(model) habit.copyFrom(model)
assertThat(habit.isArchived, CoreMatchers.`is`(model.isArchived)) assertTrue(habit.isArchived == model.isArchived)
assertThat(habit.color, CoreMatchers.`is`(model.color)) assertThat(habit.isArchived, `is`(model.isArchived))
assertThat(habit.frequency, CoreMatchers.equalTo(model.frequency)) assertThat(habit.color, `is`(model.color))
assertThat(habit.reminder, CoreMatchers.equalTo(model.reminder)) assertThat(habit.frequency, equalTo(model.frequency))
assertThat(habit.reminder, equalTo(model.reminder))
} }
@Test @Test
fun test_hasReminder() { fun test_hasReminder() {
val h = modelFactory.buildHabit() val h = modelFactory.buildHabit()
assertThat(h.hasReminder(), CoreMatchers.`is`(false)) assertThat(h.hasReminder(), `is`(false))
h.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) h.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY)
assertThat(h.hasReminder(), CoreMatchers.`is`(true)) assertThat(h.hasReminder(), `is`(true))
} }
@Test @Test
@ -116,10 +115,7 @@ class HabitTest : BaseUnitTest() {
assertTrue(habitList.isEmpty) assertTrue(habitList.isEmpty)
val h = modelFactory.buildHabit() val h = modelFactory.buildHabit()
habitList.add(h) habitList.add(h)
assertThat(h.id, CoreMatchers.equalTo(0L)) assertThat(h.id, equalTo(0L))
assertThat( assertThat(h.uriString, equalTo("content://org.isoron.uhabits/habit/0"))
h.uriString,
CoreMatchers.equalTo("content://org.isoron.uhabits/habit/0")
)
} }
} }

@ -36,56 +36,26 @@ class ScoreTest : BaseUnitTest() {
fun test_compute_withDailyHabit() { fun test_compute_withDailyHabit() {
var check = 1 var check = 1
val freq = 1.0 val freq = 1.0
assertThat( assertThat(compute(freq, 0.0, check.toDouble()), IsCloseTo.closeTo(0.051922, E))
compute(freq, 0.0, check.toDouble()), assertThat(compute(freq, 0.5, check.toDouble()), IsCloseTo.closeTo(0.525961, E))
IsCloseTo.closeTo(0.051922, E) assertThat(compute(freq, 0.75, check.toDouble()), IsCloseTo.closeTo(0.762981, E))
)
assertThat(
compute(freq, 0.5, check.toDouble()),
IsCloseTo.closeTo(0.525961, E)
)
assertThat(
compute(freq, 0.75, check.toDouble()),
IsCloseTo.closeTo(0.762981, E)
)
check = 0 check = 0
assertThat(compute(freq, 0.0, check.toDouble()), IsCloseTo.closeTo(0.0, E)) assertThat(compute(freq, 0.0, check.toDouble()), IsCloseTo.closeTo(0.0, E))
assertThat( assertThat(compute(freq, 0.5, check.toDouble()), IsCloseTo.closeTo(0.474039, E))
compute(freq, 0.5, check.toDouble()), assertThat(compute(freq, 0.75, check.toDouble()), IsCloseTo.closeTo(0.711058, E))
IsCloseTo.closeTo(0.474039, E)
)
assertThat(
compute(freq, 0.75, check.toDouble()),
IsCloseTo.closeTo(0.711058, E)
)
} }
@Test @Test
fun test_compute_withNonDailyHabit() { fun test_compute_withNonDailyHabit() {
var check = 1 var check = 1
val freq = 1 / 3.0 val freq = 1 / 3.0
assertThat( assertThat(compute(freq, 0.0, check.toDouble()), IsCloseTo.closeTo(0.030314, E))
compute(freq, 0.0, check.toDouble()), assertThat(compute(freq, 0.5, check.toDouble()), IsCloseTo.closeTo(0.515157, E))
IsCloseTo.closeTo(0.030314, E) assertThat(compute(freq, 0.75, check.toDouble()), IsCloseTo.closeTo(0.757578, E))
)
assertThat(
compute(freq, 0.5, check.toDouble()),
IsCloseTo.closeTo(0.515157, E)
)
assertThat(
compute(freq, 0.75, check.toDouble()),
IsCloseTo.closeTo(0.757578, E)
)
check = 0 check = 0
assertThat(compute(freq, 0.0, check.toDouble()), IsCloseTo.closeTo(0.0, E)) assertThat(compute(freq, 0.0, check.toDouble()), IsCloseTo.closeTo(0.0, E))
assertThat( assertThat(compute(freq, 0.5, check.toDouble()), IsCloseTo.closeTo(0.484842, E))
compute(freq, 0.5, check.toDouble()), assertThat(compute(freq, 0.75, check.toDouble()), IsCloseTo.closeTo(0.727263, E))
IsCloseTo.closeTo(0.484842, E)
)
assertThat(
compute(freq, 0.75, check.toDouble()),
IsCloseTo.closeTo(0.727263, E)
)
} }
companion object { companion object {

@ -18,16 +18,16 @@
*/ */
package org.isoron.uhabits.core.models package org.isoron.uhabits.core.models
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday
import org.junit.Test import org.junit.Test
class StreakListTest : BaseUnitTest() { class StreakListTest : BaseUnitTest() {
private lateinit var habit: Habit private lateinit var habit: Habit
private var streaks: StreakList? = null private lateinit var streaks: StreakList
private var today: Timestamp? = null private lateinit var today: Timestamp
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
@ -42,26 +42,26 @@ class StreakListTest : BaseUnitTest() {
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testGetBest() { fun testGetBest() {
var best = streaks!!.getBest(4) var best = streaks.getBest(4)
assertThat(best.size, IsEqual.equalTo(4)) assertThat(best.size, equalTo(4))
assertThat(best[0].length, IsEqual.equalTo(4)) assertThat(best[0].length, equalTo(4))
assertThat(best[1].length, IsEqual.equalTo(3)) assertThat(best[1].length, equalTo(3))
assertThat(best[2].length, IsEqual.equalTo(5)) assertThat(best[2].length, equalTo(5))
assertThat(best[3].length, IsEqual.equalTo(6)) assertThat(best[3].length, equalTo(6))
best = streaks!!.getBest(2) best = streaks.getBest(2)
assertThat(best.size, IsEqual.equalTo(2)) assertThat(best.size, equalTo(2))
assertThat(best[0].length, IsEqual.equalTo(5)) assertThat(best[0].length, equalTo(5))
assertThat(best[1].length, IsEqual.equalTo(6)) assertThat(best[1].length, equalTo(6))
} }
@Test @Test
fun testGetBest_withUnknowns() { fun testGetBest_withUnknowns() {
habit.originalEntries.clear() habit.originalEntries.clear()
habit.originalEntries.add(Entry(today!!, Entry.YES_MANUAL)) habit.originalEntries.add(Entry(today, Entry.YES_MANUAL))
habit.originalEntries.add(Entry(today!!.minus(5), Entry.NO)) habit.originalEntries.add(Entry(today.minus(5), Entry.NO))
habit.recompute() habit.recompute()
val best = streaks!!.getBest(5) val best = streaks.getBest(5)
assertThat(best.size, IsEqual.equalTo(1)) assertThat(best.size, equalTo(1))
assertThat(best[0].length, IsEqual.equalTo(1)) assertThat(best[0].length, equalTo(1))
} }
} }

@ -18,8 +18,8 @@
*/ */
package org.isoron.uhabits.core.models package org.isoron.uhabits.core.models
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import junit.framework.TestCase
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.greaterThan import org.hamcrest.Matchers.greaterThan
@ -39,10 +39,10 @@ class TimestampTest : BaseUnitTest() {
assertThat(t1.compareTo(t1), equalTo(0)) assertThat(t1.compareTo(t1), equalTo(0))
assertThat(t1.compareTo(t3), lessThan(0)) assertThat(t1.compareTo(t3), lessThan(0))
assertTrue(t1.isNewerThan(t2)) assertTrue(t1.isNewerThan(t2))
TestCase.assertFalse(t1.isNewerThan(t1)) assertFalse(t1.isNewerThan(t1))
TestCase.assertFalse(t2.isNewerThan(t1)) assertFalse(t2.isNewerThan(t1))
assertTrue(t2.isOlderThan(t1)) assertTrue(t2.isOlderThan(t1))
TestCase.assertFalse(t1.isOlderThan(t2)) assertFalse(t1.isOlderThan(t2))
} }
@Test @Test

@ -20,8 +20,8 @@ package org.isoron.uhabits.core.models
import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.junit.Test import org.junit.Test
@ -29,21 +29,13 @@ class WeekdayListTest : BaseUnitTest() {
@Test @Test
fun test() { fun test() {
val daysInt = 124 val daysInt = 124
val daysArray = booleanArrayOf( val daysArray = booleanArrayOf(false, false, true, true, true, true, true)
false,
false,
true,
true,
true,
true,
true
)
var list = WeekdayList(daysArray) var list = WeekdayList(daysArray)
assertThat(list.toArray(), IsEqual.equalTo(daysArray)) assertThat(list.toArray(), equalTo(daysArray))
assertThat(list.toInteger(), IsEqual.equalTo(daysInt)) assertThat(list.toInteger(), equalTo(daysInt))
list = WeekdayList(daysInt) list = WeekdayList(daysInt)
assertThat(list.toArray(), IsEqual.equalTo(daysArray)) assertThat(list.toArray(), equalTo(daysArray))
assertThat(list.toInteger(), IsEqual.equalTo(daysInt)) assertThat(list.toInteger(), equalTo(daysInt))
} }
@Test @Test

@ -20,7 +20,6 @@
package org.isoron.uhabits.core.models.sqlite package org.isoron.uhabits.core.models.sqlite
import junit.framework.Assert.assertEquals import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertNotNull
import junit.framework.Assert.assertNull import junit.framework.Assert.assertNull
import org.isoron.uhabits.core.BaseUnitTest.Companion.buildMemoryDatabase import org.isoron.uhabits.core.BaseUnitTest.Companion.buildMemoryDatabase
import org.isoron.uhabits.core.database.Repository import org.isoron.uhabits.core.database.Repository
@ -87,22 +86,17 @@ class SQLiteEntryListTest {
val original = Entry(today, 150) val original = Entry(today, 150)
entries.add(original) entries.add(original)
val retrieved = getByTimestamp(1, today) val retrieved = getByTimestamp(1, today)!!
assertNotNull(retrieved) assertEquals(original, retrieved.toEntry())
assertEquals(original, retrieved!!.toEntry())
val replacement = Entry(today, 90) val replacement = Entry(today, 90)
entries.add(replacement) entries.add(replacement)
val retrieved2 = getByTimestamp(1, today) val retrieved2 = getByTimestamp(1, today)!!
assertNotNull(retrieved2) assertEquals(replacement, retrieved2.toEntry())
assertEquals(replacement, retrieved2!!.toEntry())
} }
private fun getByTimestamp( private fun getByTimestamp(habitId: Int, timestamp: Timestamp): EntryRecord? {
habitId: Int,
timestamp: Timestamp,
): EntryRecord? {
return repository.findFirst( return repository.findFirst(
"where habit = ? and timestamp = ?", "where habit = ? and timestamp = ?",
habitId.toString(), habitId.toString(),

@ -18,9 +18,10 @@
*/ */
package org.isoron.uhabits.core.models.sqlite package org.isoron.uhabits.core.models.sqlite
import junit.framework.Assert.assertNotNull import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import junit.framework.Assert.assertNull import junit.framework.Assert.assertNull
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.database.Database import org.isoron.uhabits.core.database.Database
@ -36,17 +37,17 @@ import org.isoron.uhabits.core.test.HabitFixtures
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.ExpectedException import org.junit.rules.ExpectedException
import org.mockito.Mockito
import java.util.ArrayList import java.util.ArrayList
class SQLiteHabitListTest : BaseUnitTest() { class SQLiteHabitListTest : BaseUnitTest() {
@get:Rule @get:Rule
var exception = ExpectedException.none()!! var exception = ExpectedException.none()!!
private lateinit var repository: Repository<HabitRecord> private lateinit var repository: Repository<HabitRecord>
private lateinit var listener: ModelObservable.Listener private var listener: ModelObservable.Listener = mock()
private lateinit var habitsArray: ArrayList<Habit> private lateinit var habitsArray: ArrayList<Habit>
private lateinit var activeHabits: HabitList private lateinit var activeHabits: HabitList
private lateinit var reminderHabits: HabitList private lateinit var reminderHabits: HabitList
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
@ -54,10 +55,7 @@ class SQLiteHabitListTest : BaseUnitTest() {
modelFactory = SQLModelFactory(db) modelFactory = SQLModelFactory(db)
habitList = SQLiteHabitList(modelFactory) habitList = SQLiteHabitList(modelFactory)
fixtures = HabitFixtures(modelFactory, habitList) fixtures = HabitFixtures(modelFactory, habitList)
repository = Repository( repository = Repository(HabitRecord::class.java, db)
HabitRecord::class.java,
db
)
habitsArray = ArrayList() habitsArray = ArrayList()
for (i in 0..9) { for (i in 0..9) {
val habit = fixtures.createEmptyHabit() val habit = fixtures.createEmptyHabit()
@ -78,7 +76,6 @@ class SQLiteHabitListTest : BaseUnitTest() {
.setReminderRequired(true) .setReminderRequired(true)
.build() .build()
) )
listener = Mockito.mock(ModelObservable.Listener::class.java)
habitList.observable.addListener(listener) habitList.observable.addListener(listener)
} }
@ -92,7 +89,7 @@ class SQLiteHabitListTest : BaseUnitTest() {
fun testAdd_withDuplicate() { fun testAdd_withDuplicate() {
val habit = modelFactory.buildHabit() val habit = modelFactory.buildHabit()
habitList.add(habit) habitList.add(habit)
Mockito.verify(listener)!!.onModelChange() verify(listener).onModelChange()
exception.expect(IllegalArgumentException::class.java) exception.expect(IllegalArgumentException::class.java)
habitList.add(habit) habitList.add(habit)
} }
@ -103,10 +100,9 @@ class SQLiteHabitListTest : BaseUnitTest() {
habit.name = "Hello world with id" habit.name = "Hello world with id"
habit.id = 12300L habit.id = 12300L
habitList.add(habit) habitList.add(habit)
assertThat(habit.id, CoreMatchers.equalTo(12300L)) assertThat(habit.id, equalTo(12300L))
val record = repository.find(12300L) val record = repository.find(12300L)
assertNotNull(record) assertThat(record!!.name, equalTo(habit.name))
assertThat(record!!.name, CoreMatchers.equalTo(habit.name))
} }
@Test @Test
@ -115,27 +111,21 @@ class SQLiteHabitListTest : BaseUnitTest() {
habit.name = "Hello world" habit.name = "Hello world"
assertNull(habit.id) assertNull(habit.id)
habitList.add(habit) habitList.add(habit)
assertNotNull(habit.id) val record = repository.find(habit.id!!)
val record = repository.find( assertThat(record!!.name, equalTo(habit.name))
habit.id!!
)
assertNotNull(record)
assertThat(record!!.name, CoreMatchers.equalTo(habit.name))
} }
@Test @Test
fun testSize() { fun testSize() {
assertThat(habitList.size(), CoreMatchers.equalTo(10)) assertThat(habitList.size(), equalTo(10))
} }
@Test @Test
fun testGetById() { fun testGetById() {
val h1 = habitList.getById(1) val h1 = habitList.getById(1)!!
assertNotNull(h1) assertThat(h1.name, equalTo("habit 1"))
assertThat(h1!!.name, CoreMatchers.equalTo("habit 1")) val h2 = habitList.getById(2)!!
val h2 = habitList.getById(2) assertThat(h2, equalTo(h2))
assertNotNull(h2)
assertThat(h2, CoreMatchers.equalTo(h2))
} }
@Test @Test
@ -148,19 +138,17 @@ class SQLiteHabitListTest : BaseUnitTest() {
@Test @Test
fun testGetByPosition() { fun testGetByPosition() {
val h = habitList.getByPosition(4) val h = habitList.getByPosition(4)
assertNotNull(h) assertThat(h.name, equalTo("habit 5"))
assertThat(h.name, CoreMatchers.equalTo("habit 5"))
} }
@Test @Test
fun testIndexOf() { fun testIndexOf() {
val h1 = habitList.getByPosition(5) val h1 = habitList.getByPosition(5)
assertNotNull(h1) assertThat(habitList.indexOf(h1), equalTo(5))
assertThat(habitList.indexOf(h1), CoreMatchers.equalTo(5))
val h2 = modelFactory.buildHabit() val h2 = modelFactory.buildHabit()
assertThat(habitList.indexOf(h2), CoreMatchers.equalTo(-1)) assertThat(habitList.indexOf(h2), equalTo(-1))
h2.id = 1000L h2.id = 1000L
assertThat(habitList.indexOf(h2), CoreMatchers.equalTo(-1)) assertThat(habitList.indexOf(h2), equalTo(-1))
} }
@Test @Test
@ -168,26 +156,21 @@ class SQLiteHabitListTest : BaseUnitTest() {
fun testRemove() { fun testRemove() {
val h = habitList.getById(2) val h = habitList.getById(2)
habitList.remove(h!!) habitList.remove(h!!)
assertThat(habitList.indexOf(h), CoreMatchers.equalTo(-1)) assertThat(habitList.indexOf(h), equalTo(-1))
var rec = repository.find(2L) var rec = repository.find(2L)
assertNull(rec) assertNull(rec)
rec = repository.find(3L) rec = repository.find(3L)!!
assertNotNull(rec) assertThat(rec.position, equalTo(1))
assertThat(rec!!.position, CoreMatchers.equalTo(1))
} }
@Test @Test
fun testReorder() { fun testReorder() {
val habit3 = habitList.getById(3) val habit3 = habitList.getById(3)!!
val habit4 = habitList.getById(4) val habit4 = habitList.getById(4)!!
assertNotNull(habit3) habitList.reorder(habit4, habit3)
assertNotNull(habit4) val record3 = repository.find(3L)!!
habitList.reorder(habit4!!, habit3!!) assertThat(record3.position, equalTo(3))
val record3 = repository.find(3L) val record4 = repository.find(4L)!!
assertNotNull(record3) assertThat(record4.position, equalTo(2))
assertThat(record3!!.position, CoreMatchers.equalTo(3))
val record4 = repository.find(4L)
assertNotNull(record4)
assertThat(record4!!.position, CoreMatchers.equalTo(2))
} }
} }

@ -18,8 +18,8 @@
*/ */
package org.isoron.uhabits.core.models.sqlite.records package org.isoron.uhabits.core.models.sqlite.records
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
@ -32,6 +32,6 @@ class EntryRecordTest : BaseUnitTest() {
val check = Entry(Timestamp.ZERO.plus(100), 50) val check = Entry(Timestamp.ZERO.plus(100), 50)
val record = EntryRecord() val record = EntryRecord()
record.copyFrom(check) record.copyFrom(check)
assertThat(check, IsEqual.equalTo(record.toEntry())) assertThat(check, equalTo(record.toEntry()))
} }
} }

@ -18,8 +18,8 @@
*/ */
package org.isoron.uhabits.core.models.sqlite.records package org.isoron.uhabits.core.models.sqlite.records
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@ -31,41 +31,43 @@ import org.junit.Test
class HabitRecordTest : BaseUnitTest() { class HabitRecordTest : BaseUnitTest() {
@Test @Test
fun testCopyRestore1() { fun testCopyRestore1() {
val original = modelFactory.buildHabit() val original = modelFactory.buildHabit().apply() {
original.name = "Hello world" name = "Hello world"
original.question = "Did you greet the world today?" question = "Did you greet the world today?"
original.color = PaletteColor(1) color = PaletteColor(1)
original.isArchived = true isArchived = true
original.frequency = Frequency.THREE_TIMES_PER_WEEK frequency = Frequency.THREE_TIMES_PER_WEEK
original.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) reminder = Reminder(8, 30, WeekdayList.EVERY_DAY)
original.id = 1000L id = 1000L
original.position = 20 position = 20
}
val record = HabitRecord() val record = HabitRecord()
record.copyFrom(original) record.copyFrom(original)
val duplicate = modelFactory.buildHabit() val duplicate = modelFactory.buildHabit()
record.copyTo(duplicate) record.copyTo(duplicate)
assertThat(original, IsEqual.equalTo(duplicate)) assertThat(original, equalTo(duplicate))
} }
@Test @Test
fun testCopyRestore2() { fun testCopyRestore2() {
val original = modelFactory.buildHabit() val original = modelFactory.buildHabit().apply() {
original.name = "Hello world" name = "Hello world"
original.question = "Did you greet the world today?" question = "Did you greet the world today?"
original.color = PaletteColor(5) color = PaletteColor(5)
original.isArchived = false isArchived = false
original.frequency = Frequency.DAILY frequency = Frequency.DAILY
original.reminder = null reminder = null
original.id = 1L id = 1L
original.position = 15 position = 15
original.type = Habit.NUMBER_HABIT type = Habit.NUMBER_HABIT
original.targetValue = 100.0 targetValue = 100.0
original.targetType = Habit.AT_LEAST targetType = Habit.AT_LEAST
original.unit = "miles" unit = "miles"
}
val record = HabitRecord() val record = HabitRecord()
record.copyFrom(original) record.copyFrom(original)
val duplicate = modelFactory.buildHabit() val duplicate = modelFactory.buildHabit()
record.copyTo(duplicate) record.copyTo(duplicate)
assertThat(original, IsEqual.equalTo(duplicate)) assertThat(original, equalTo(duplicate))
} }
} }

@ -18,26 +18,25 @@
*/ */
package org.isoron.uhabits.core.preferences package org.isoron.uhabits.core.preferences
import com.nhaarman.mockitokotlin2.mock
import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertNull import junit.framework.Assert.assertNull
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp.ZERO
import org.isoron.uhabits.core.ui.ThemeSwitcher import org.isoron.uhabits.core.ui.ThemeSwitcher
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.Mock
import java.io.File import java.io.File
class PreferencesTest : BaseUnitTest() { class PreferencesTest : BaseUnitTest() {
private lateinit var prefs: Preferences private lateinit var prefs: Preferences
@Mock private var listener: Preferences.Listener = mock()
private val listener: Preferences.Listener? = null private lateinit var storage: PropertiesStorage
private var storage: PropertiesStorage? = null
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
@ -46,7 +45,7 @@ class PreferencesTest : BaseUnitTest() {
val file = File.createTempFile("prefs", ".properties") val file = File.createTempFile("prefs", ".properties")
file.deleteOnExit() file.deleteOnExit()
storage = PropertiesStorage(file) storage = PropertiesStorage(file)
prefs = Preferences(storage!!) prefs = Preferences(storage)
prefs.addListener(listener) prefs.addListener(listener)
} }
@ -55,66 +54,57 @@ class PreferencesTest : BaseUnitTest() {
fun testClear() { fun testClear() {
prefs.setDefaultHabitColor(99) prefs.setDefaultHabitColor(99)
prefs.clear() prefs.clear()
assertThat(prefs.getDefaultHabitColor(0), IsEqual.equalTo(0)) assertThat(prefs.getDefaultHabitColor(0), equalTo(0))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testHabitColor() { fun testHabitColor() {
assertThat(prefs.getDefaultHabitColor(999), IsEqual.equalTo(999)) assertThat(prefs.getDefaultHabitColor(999), equalTo(999))
prefs.setDefaultHabitColor(10) prefs.setDefaultHabitColor(10)
assertThat(prefs.getDefaultHabitColor(999), IsEqual.equalTo(10)) assertThat(prefs.getDefaultHabitColor(999), equalTo(10))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testDefaultOrder() { fun testDefaultOrder() {
assertThat( assertThat(prefs.defaultPrimaryOrder, equalTo(HabitList.Order.BY_POSITION))
prefs.defaultPrimaryOrder,
IsEqual.equalTo(HabitList.Order.BY_POSITION)
)
prefs.defaultPrimaryOrder = HabitList.Order.BY_SCORE_DESC prefs.defaultPrimaryOrder = HabitList.Order.BY_SCORE_DESC
assertThat(prefs.defaultPrimaryOrder, equalTo(HabitList.Order.BY_SCORE_DESC))
storage.putString("pref_default_order", "BOGUS")
assertThat(prefs.defaultPrimaryOrder, equalTo(HabitList.Order.BY_POSITION))
assertThat( assertThat(
prefs.defaultPrimaryOrder, storage.getString("pref_default_order", ""),
IsEqual.equalTo(HabitList.Order.BY_SCORE_DESC) equalTo("BY_POSITION")
)
storage!!.putString("pref_default_order", "BOGUS")
assertThat(
prefs.defaultPrimaryOrder,
IsEqual.equalTo(HabitList.Order.BY_POSITION)
)
assertThat(
storage!!.getString("pref_default_order", ""),
IsEqual.equalTo("BY_POSITION")
) )
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testScoreCardSpinnerPosition() { fun testScoreCardSpinnerPosition() {
assertThat(prefs.scoreCardSpinnerPosition, IsEqual.equalTo(1)) assertThat(prefs.scoreCardSpinnerPosition, equalTo(1))
prefs.scoreCardSpinnerPosition = 4 prefs.scoreCardSpinnerPosition = 4
assertThat(prefs.scoreCardSpinnerPosition, IsEqual.equalTo(4)) assertThat(prefs.scoreCardSpinnerPosition, equalTo(4))
storage!!.putInt("pref_score_view_interval", 9000) storage.putInt("pref_score_view_interval", 9000)
assertThat(prefs.scoreCardSpinnerPosition, IsEqual.equalTo(4)) assertThat(prefs.scoreCardSpinnerPosition, equalTo(4))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testLastHint() { fun testLastHint() {
assertThat(prefs.lastHintNumber, IsEqual.equalTo(-1)) assertThat(prefs.lastHintNumber, equalTo(-1))
assertNull(prefs.lastHintTimestamp) assertNull(prefs.lastHintTimestamp)
prefs.updateLastHint(34, Timestamp.ZERO.plus(100)) prefs.updateLastHint(34, ZERO.plus(100))
assertThat(prefs.lastHintNumber, IsEqual.equalTo(34)) assertThat(prefs.lastHintNumber, equalTo(34))
assertThat(prefs.lastHintTimestamp, IsEqual.equalTo(Timestamp.ZERO.plus(100))) assertThat(prefs.lastHintTimestamp, equalTo(ZERO.plus(100)))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testTheme() { fun testTheme() {
assertThat(prefs.theme, IsEqual.equalTo(ThemeSwitcher.THEME_AUTOMATIC)) assertThat(prefs.theme, equalTo(ThemeSwitcher.THEME_AUTOMATIC))
prefs.theme = ThemeSwitcher.THEME_DARK prefs.theme = ThemeSwitcher.THEME_DARK
assertThat(prefs.theme, IsEqual.equalTo(ThemeSwitcher.THEME_DARK)) assertThat(prefs.theme, equalTo(ThemeSwitcher.THEME_DARK))
assertFalse(prefs.isPureBlackEnabled) assertFalse(prefs.isPureBlackEnabled)
prefs.isPureBlackEnabled = true prefs.isPureBlackEnabled = true
assertTrue(prefs.isPureBlackEnabled) assertTrue(prefs.isPureBlackEnabled)
@ -129,23 +119,23 @@ class PreferencesTest : BaseUnitTest() {
assertFalse(prefs.shouldMakeNotificationsLed()) assertFalse(prefs.shouldMakeNotificationsLed())
prefs.setNotificationsLed(true) prefs.setNotificationsLed(true)
assertTrue(prefs.shouldMakeNotificationsLed()) assertTrue(prefs.shouldMakeNotificationsLed())
assertThat(prefs.snoozeInterval, IsEqual.equalTo(15L)) assertThat(prefs.snoozeInterval, equalTo(15L))
prefs.setSnoozeInterval(30) prefs.setSnoozeInterval(30)
assertThat(prefs.snoozeInterval, IsEqual.equalTo(30L)) assertThat(prefs.snoozeInterval, equalTo(30L))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testAppVersionAndLaunch() { fun testAppVersionAndLaunch() {
assertThat(prefs.lastAppVersion, IsEqual.equalTo(0)) assertThat(prefs.lastAppVersion, equalTo(0))
prefs.lastAppVersion = 23 prefs.lastAppVersion = 23
assertThat(prefs.lastAppVersion, IsEqual.equalTo(23)) assertThat(prefs.lastAppVersion, equalTo(23))
assertTrue(prefs.isFirstRun) assertTrue(prefs.isFirstRun)
prefs.isFirstRun = false prefs.isFirstRun = false
assertFalse(prefs.isFirstRun) assertFalse(prefs.isFirstRun)
assertThat(prefs.launchCount, IsEqual.equalTo(0)) assertThat(prefs.launchCount, equalTo(0))
prefs.incrementLaunchCount() prefs.incrementLaunchCount()
assertThat(prefs.launchCount, IsEqual.equalTo(1)) assertThat(prefs.launchCount, equalTo(1))
} }
@Test @Test

@ -18,10 +18,11 @@
*/ */
package org.isoron.uhabits.core.preferences package org.isoron.uhabits.core.preferences
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import junit.framework.TestCase import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
@ -29,7 +30,7 @@ import java.io.File
import java.util.Arrays import java.util.Arrays
class PropertiesStorageTest : BaseUnitTest() { class PropertiesStorageTest : BaseUnitTest() {
private var storage: PropertiesStorage? = null private lateinit var storage: PropertiesStorage
private lateinit var file: File private lateinit var file: File
@Before @Before
@ -44,39 +45,37 @@ class PropertiesStorageTest : BaseUnitTest() {
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testPutGetRemove() { fun testPutGetRemove() {
storage!!.putBoolean("booleanKey", true) storage.putBoolean("booleanKey", true)
assertTrue(storage!!.getBoolean("booleanKey", false)) assertTrue(storage.getBoolean("booleanKey", false))
TestCase.assertFalse(storage!!.getBoolean("random", false)) assertFalse(storage.getBoolean("random", false))
storage!!.putInt("intKey", 64) storage.putInt("intKey", 64)
assertThat(storage!!.getInt("intKey", 200), IsEqual.equalTo(64)) assertThat(storage.getInt("intKey", 200), equalTo(64))
assertThat(storage!!.getInt("random", 200), IsEqual.equalTo(200)) assertThat(storage.getInt("random", 200), equalTo(200))
storage!!.putLong("longKey", 64L) storage.putLong("longKey", 64L)
assertThat(storage!!.getLong("intKey", 200L), IsEqual.equalTo(64L)) assertThat(storage.getLong("intKey", 200L), equalTo(64L))
assertThat(storage!!.getLong("random", 200L), IsEqual.equalTo(200L)) assertThat(storage.getLong("random", 200L), equalTo(200L))
storage!!.putString("stringKey", "Hello") storage.putString("stringKey", "Hello")
assertThat(storage!!.getString("stringKey", ""), IsEqual.equalTo("Hello")) assertThat(storage.getString("stringKey", ""), equalTo("Hello"))
assertThat(storage!!.getString("random", ""), IsEqual.equalTo("")) assertThat(storage.getString("random", ""), equalTo(""))
storage!!.remove("stringKey") storage.remove("stringKey")
assertThat(storage!!.getString("stringKey", ""), IsEqual.equalTo("")) assertThat(storage.getString("stringKey", ""), equalTo(""))
storage!!.clear() storage.clear()
assertThat(storage!!.getLong("intKey", 200L), IsEqual.equalTo(200L)) assertThat(storage.getLong("intKey", 200L), equalTo(200L))
TestCase.assertFalse(storage!!.getBoolean("booleanKey", false)) assertFalse(storage.getBoolean("booleanKey", false))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testPersistence() { fun testPersistence() {
storage!!.putBoolean("booleanKey", true) storage.putBoolean("booleanKey", true)
storage!!.putInt("intKey", 64) storage.putInt("intKey", 64)
storage!!.putLong("longKey", 64L) storage.putLong("longKey", 64L)
storage!!.putString("stringKey", "Hello") storage.putString("stringKey", "Hello")
val storage2 = PropertiesStorage( val storage2 = PropertiesStorage(file)
file
)
assertTrue(storage2.getBoolean("booleanKey", false)) assertTrue(storage2.getBoolean("booleanKey", false))
assertThat(storage2.getInt("intKey", 200), IsEqual.equalTo(64)) assertThat(storage2.getInt("intKey", 200), equalTo(64))
assertThat(storage2.getLong("intKey", 200L), IsEqual.equalTo(64L)) assertThat(storage2.getLong("intKey", 200L), equalTo(64L))
assertThat(storage2.getString("stringKey", ""), IsEqual.equalTo("Hello")) assertThat(storage2.getString("stringKey", ""), equalTo("Hello"))
} }
@Test @Test
@ -86,18 +85,18 @@ class PropertiesStorageTest : BaseUnitTest() {
val expected2 = longArrayOf(1L) val expected2 = longArrayOf(1L)
val expected3 = longArrayOf() val expected3 = longArrayOf()
val expected4 = longArrayOf() val expected4 = longArrayOf()
storage!!.putLongArray("key1", expected1) storage.putLongArray("key1", expected1)
storage!!.putLongArray("key2", expected2) storage.putLongArray("key2", expected2)
storage!!.putLongArray("key3", expected3) storage.putLongArray("key3", expected3)
val actual1 = storage!!.getLongArray("key1", longArrayOf()) val actual1 = storage.getLongArray("key1", longArrayOf())
val actual2 = storage!!.getLongArray("key2", longArrayOf()) val actual2 = storage.getLongArray("key2", longArrayOf())
val actual3 = storage!!.getLongArray("key3", longArrayOf()) val actual3 = storage.getLongArray("key3", longArrayOf())
val actual4 = storage!!.getLongArray("invalidKey", longArrayOf()) val actual4 = storage.getLongArray("invalidKey", longArrayOf())
assertTrue(Arrays.equals(actual1, expected1)) assertTrue(Arrays.equals(actual1, expected1))
assertTrue(Arrays.equals(actual2, expected2)) assertTrue(Arrays.equals(actual2, expected2))
assertTrue(Arrays.equals(actual3, expected3)) assertTrue(Arrays.equals(actual3, expected3))
assertTrue(Arrays.equals(actual4, expected4)) assertTrue(Arrays.equals(actual4, expected4))
TestCase.assertEquals("1,2,3,5", storage!!.getString("key1", "")) assertEquals("1,2,3,5", storage.getString("key1", ""))
TestCase.assertEquals(1, storage!!.getLong("key2", -1)) assertEquals(1, storage.getLong("key2", -1))
} }
} }

@ -18,6 +18,10 @@
*/ */
package org.isoron.uhabits.core.reminders package org.isoron.uhabits.core.reminders
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.Reminder import org.isoron.uhabits.core.models.Reminder
@ -31,9 +35,7 @@ import org.isoron.uhabits.core.utils.DateUtils.Companion.setFixedTimeZone
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnitRunner import org.mockito.junit.MockitoJUnitRunner
import java.util.Calendar import java.util.Calendar
import java.util.TimeZone import java.util.TimeZone
@ -41,22 +43,20 @@ import java.util.TimeZone
@RunWith(MockitoJUnitRunner::class) @RunWith(MockitoJUnitRunner::class)
class ReminderSchedulerTest : BaseUnitTest() { class ReminderSchedulerTest : BaseUnitTest() {
private val habitId = 10L private val habitId = 10L
private var habit: Habit? = null private lateinit var habit: Habit
private var reminderScheduler: ReminderScheduler? = null private lateinit var reminderScheduler: ReminderScheduler
@Mock private val sys: ReminderScheduler.SystemScheduler = mock()
private val sys: ReminderScheduler.SystemScheduler? = null private val widgetPreferences: WidgetPreferences = mock()
@Mock
private val widgetPreferences: WidgetPreferences? = null
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
habit = fixtures.createEmptyHabit() habit = fixtures.createEmptyHabit()
habit!!.id = habitId habit.id = habitId
reminderScheduler = reminderScheduler =
ReminderScheduler(commandRunner, habitList, sys!!, widgetPreferences!!) ReminderScheduler(commandRunner, habitList, sys, widgetPreferences)
setFixedTimeZone(TimeZone.getTimeZone("GMT-4")) setFixedTimeZone(TimeZone.getTimeZone("GMT-4"))
} }
@ -73,16 +73,16 @@ class ReminderSchedulerTest : BaseUnitTest() {
habitList.add(h1) habitList.add(h1)
habitList.add(h2) habitList.add(h2)
habitList.add(h3) habitList.add(h3)
reminderScheduler!!.scheduleAll() reminderScheduler.scheduleAll()
Mockito.verify(sys)!!.scheduleShowReminder( verify(sys).scheduleShowReminder(
ArgumentMatchers.eq(unixTime(2015, 1, 27, 12, 30)), eq(unixTime(2015, 1, 27, 12, 30)),
ArgumentMatchers.eq(h1), eq(h1),
ArgumentMatchers.anyLong() anyLong()
) )
Mockito.verify(sys)!!.scheduleShowReminder( verify(sys).scheduleShowReminder(
ArgumentMatchers.eq(unixTime(2015, 1, 26, 22, 30)), eq(unixTime(2015, 1, 26, 22, 30)),
ArgumentMatchers.eq(h2), eq(h2),
ArgumentMatchers.anyLong() anyLong()
) )
} }
@ -90,7 +90,7 @@ class ReminderSchedulerTest : BaseUnitTest() {
fun testSchedule_atSpecificTime() { fun testSchedule_atSpecificTime() {
val atTime = unixTime(2015, 1, 30, 11, 30) val atTime = unixTime(2015, 1, 30, 11, 30)
val expectedCheckmarkTime = unixTime(2015, 1, 30, 0, 0) val expectedCheckmarkTime = unixTime(2015, 1, 30, 0, 0)
habit!!.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) habit.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY)
scheduleAndVerify(atTime, expectedCheckmarkTime, atTime) scheduleAndVerify(atTime, expectedCheckmarkTime, atTime)
} }
@ -103,13 +103,14 @@ class ReminderSchedulerTest : BaseUnitTest() {
val regularReminderTime = applyTimezone(unixTime(2015, 1, 2, 8, 30)) val regularReminderTime = applyTimezone(unixTime(2015, 1, 2, 8, 30))
val todayCheckmarkTime = unixTime(2015, 1, 1, 0, 0) val todayCheckmarkTime = unixTime(2015, 1, 1, 0, 0)
val tomorrowCheckmarkTime = unixTime(2015, 1, 2, 0, 0) val tomorrowCheckmarkTime = unixTime(2015, 1, 2, 0, 0)
habit!!.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) habit.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY)
Mockito.`when`(widgetPreferences!!.getSnoozeTime(habitId)).thenReturn(snoozeTimeInFuture) whenever(widgetPreferences.getSnoozeTime(habitId)).thenReturn(snoozeTimeInFuture)
reminderScheduler!!.schedule(habit!!) reminderScheduler.schedule(habit)
Mockito.verify(sys)!!.scheduleShowReminder(snoozeTimeInFuture, habit, todayCheckmarkTime) verify(sys).scheduleShowReminder(snoozeTimeInFuture, habit, todayCheckmarkTime)
Mockito.`when`(widgetPreferences.getSnoozeTime(habitId)).thenReturn(snoozeTimeInPast) whenever(widgetPreferences.getSnoozeTime(habitId)).thenReturn(snoozeTimeInPast)
reminderScheduler!!.schedule(habit!!) reminderScheduler.schedule(habit)
Mockito.verify(sys)!!.scheduleShowReminder(regularReminderTime, habit, tomorrowCheckmarkTime) verify(sys)
.scheduleShowReminder(regularReminderTime, habit, tomorrowCheckmarkTime)
} }
@Test @Test
@ -118,7 +119,7 @@ class ReminderSchedulerTest : BaseUnitTest() {
setFixedLocalTime(now) setFixedLocalTime(now)
val expectedCheckmarkTime = unixTime(2015, 1, 26, 0, 0) val expectedCheckmarkTime = unixTime(2015, 1, 26, 0, 0)
val expectedReminderTime = unixTime(2015, 1, 26, 12, 30) val expectedReminderTime = unixTime(2015, 1, 26, 12, 30)
habit!!.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) habit.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY)
scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime) scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime)
} }
@ -128,13 +129,13 @@ class ReminderSchedulerTest : BaseUnitTest() {
setFixedLocalTime(now) setFixedLocalTime(now)
val expectedCheckmarkTime = unixTime(2015, 1, 27, 0, 0) val expectedCheckmarkTime = unixTime(2015, 1, 27, 0, 0)
val expectedReminderTime = unixTime(2015, 1, 27, 12, 30) val expectedReminderTime = unixTime(2015, 1, 27, 12, 30)
habit!!.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) habit.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY)
scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime) scheduleAndVerify(null, expectedCheckmarkTime, expectedReminderTime)
} }
@Test @Test
fun testSchedule_withoutReminder() { fun testSchedule_withoutReminder() {
reminderScheduler!!.schedule(habit!!) reminderScheduler.schedule(habit)
} }
override fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): Long { override fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int): Long {
@ -148,11 +149,11 @@ class ReminderSchedulerTest : BaseUnitTest() {
expectedCheckmarkTime: Long, expectedCheckmarkTime: Long,
expectedReminderTime: Long expectedReminderTime: Long
) { ) {
if (atTime == null) reminderScheduler!!.schedule(habit!!) else reminderScheduler!!.scheduleAtTime( if (atTime == null) reminderScheduler.schedule(habit) else reminderScheduler.scheduleAtTime(
habit!!, habit,
atTime atTime
) )
Mockito.verify(sys)!!.scheduleShowReminder( verify(sys).scheduleShowReminder(
expectedReminderTime, expectedReminderTime,
habit, habit,
expectedCheckmarkTime expectedCheckmarkTime

@ -18,28 +18,29 @@
*/ */
package org.isoron.uhabits.core.tasks package org.isoron.uhabits.core.tasks
import com.nhaarman.mockitokotlin2.inOrder
import com.nhaarman.mockitokotlin2.mock
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.JUnit4 import org.junit.runners.JUnit4
import org.mockito.Mockito
@RunWith(JUnit4::class) @RunWith(JUnit4::class)
class SingleThreadTaskRunnerTest : BaseUnitTest() { class SingleThreadTaskRunnerTest : BaseUnitTest() {
private var runner: SingleThreadTaskRunner? = null private lateinit var runner: SingleThreadTaskRunner
private lateinit var task: Task private var task: Task = mock()
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
runner = SingleThreadTaskRunner() runner = SingleThreadTaskRunner()
task = Mockito.mock(Task::class.java)
} }
@Test @Test
fun test() { fun test() {
runner!!.execute(task) runner.execute(task)
val inOrder = Mockito.inOrder(task) val inOrder = inOrder(task)
inOrder.verify(task).onAttached(runner!!) inOrder.verify(task).onAttached(runner)
inOrder.verify(task).onPreExecute() inOrder.verify(task).onPreExecute()
inOrder.verify(task).doInBackground() inOrder.verify(task).doInBackground()
inOrder.verify(task).onPostExecute() inOrder.verify(task).onPostExecute()

@ -18,20 +18,22 @@
*/ */
package org.isoron.uhabits.core.ui.screens.habits.list package org.isoron.uhabits.core.ui.screens.habits.list
import junit.framework.Assert.assertNotNull import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.reset
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.commands.CreateRepetitionCommand import org.isoron.uhabits.core.commands.CreateRepetitionCommand
import org.isoron.uhabits.core.commands.DeleteHabitsCommand import org.isoron.uhabits.core.commands.DeleteHabitsCommand
import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday
import org.junit.Test import org.junit.Test
import org.mockito.Mockito
class HabitCardListCacheTest : BaseUnitTest() { class HabitCardListCacheTest : BaseUnitTest() {
private var cache: HabitCardListCache? = null private lateinit var cache: HabitCardListCache
private var listener: HabitCardListCache.Listener? = null private lateinit var listener: HabitCardListCache.Listener
var today = getToday() var today = getToday()
@Throws(Exception::class) @Throws(Exception::class)
@ -42,86 +44,83 @@ class HabitCardListCacheTest : BaseUnitTest() {
if (i == 3) habitList.add(fixtures.createLongHabit()) else habitList.add(fixtures.createShortHabit()) if (i == 3) habitList.add(fixtures.createLongHabit()) else habitList.add(fixtures.createShortHabit())
} }
cache = HabitCardListCache(habitList, commandRunner, taskRunner) cache = HabitCardListCache(habitList, commandRunner, taskRunner)
cache!!.setCheckmarkCount(10) cache.setCheckmarkCount(10)
cache!!.refreshAllHabits() cache.refreshAllHabits()
cache!!.onAttached() cache.onAttached()
listener = Mockito.mock( listener = mock()
HabitCardListCache.Listener::class.java cache.setListener(listener)
)
cache!!.setListener(listener!!)
} }
override fun tearDown() { override fun tearDown() {
cache!!.onDetached() cache.onDetached()
} }
@Test @Test
fun testCommandListener_all() { fun testCommandListener_all() {
assertThat(cache!!.habitCount, IsEqual.equalTo(10)) assertThat(cache.habitCount, equalTo(10))
val h = habitList.getByPosition(0) val h = habitList.getByPosition(0)
commandRunner.run( commandRunner.run(
DeleteHabitsCommand(habitList, listOf(h)) DeleteHabitsCommand(habitList, listOf(h))
) )
Mockito.verify(listener)!!.onItemRemoved(0) verify(listener).onItemRemoved(0)
Mockito.verify(listener)!!.onRefreshFinished() verify(listener).onRefreshFinished()
assertThat(cache!!.habitCount, IsEqual.equalTo(9)) assertThat(cache.habitCount, equalTo(9))
} }
@Test @Test
fun testCommandListener_single() { fun testCommandListener_single() {
val h2 = habitList.getByPosition(2) val h2 = habitList.getByPosition(2)
commandRunner.run(CreateRepetitionCommand(habitList, h2, today, Entry.NO)) commandRunner.run(CreateRepetitionCommand(habitList, h2, today, Entry.NO))
Mockito.verify(listener)!!.onItemChanged(2) verify(listener).onItemChanged(2)
Mockito.verify(listener)!!.onRefreshFinished() verify(listener).onRefreshFinished()
Mockito.verifyNoMoreInteractions(listener) verifyNoMoreInteractions(listener)
} }
@Test @Test
fun testGet() { fun testGet() {
assertThat(cache!!.habitCount, IsEqual.equalTo(10)) assertThat(cache.habitCount, equalTo(10))
val h = habitList.getByPosition(3) val h = habitList.getByPosition(3)
assertNotNull(h.id)
val score = h.scores[today].value val score = h.scores[today].value
assertThat(cache!!.getHabitByPosition(3), IsEqual.equalTo(h)) assertThat(cache.getHabitByPosition(3), equalTo(h))
assertThat(cache!!.getScore(h.id!!), IsEqual.equalTo(score)) assertThat(cache.getScore(h.id!!), equalTo(score))
val actualCheckmarks = cache!!.getCheckmarks(h.id!!) val actualCheckmarks = cache.getCheckmarks(h.id!!)
val expectedCheckmarks = h val expectedCheckmarks = h
.computedEntries .computedEntries
.getByInterval(today.minus(9), today) .getByInterval(today.minus(9), today)
.map { it.value }.toIntArray() .map { it.value }.toIntArray()
assertThat(actualCheckmarks, IsEqual.equalTo(expectedCheckmarks)) assertThat(actualCheckmarks, equalTo(expectedCheckmarks))
} }
@Test @Test
fun testRemoval() { fun testRemoval() {
removeHabitAt(0) removeHabitAt(0)
removeHabitAt(3) removeHabitAt(3)
cache!!.refreshAllHabits() cache.refreshAllHabits()
Mockito.verify(listener)!!.onItemRemoved(0) verify(listener).onItemRemoved(0)
Mockito.verify(listener)!!.onItemRemoved(3) verify(listener).onItemRemoved(3)
Mockito.verify(listener)!!.onRefreshFinished() verify(listener).onRefreshFinished()
assertThat(cache!!.habitCount, IsEqual.equalTo(8)) assertThat(cache.habitCount, equalTo(8))
} }
@Test @Test
fun testRefreshWithNoChanges() { fun testRefreshWithNoChanges() {
cache!!.refreshAllHabits() cache.refreshAllHabits()
Mockito.verify(listener)!!.onRefreshFinished() verify(listener).onRefreshFinished()
Mockito.verifyNoMoreInteractions(listener) verifyNoMoreInteractions(listener)
} }
@Test @Test
fun testReorder_onCache() { fun testReorder_onCache() {
val h2 = cache!!.getHabitByPosition(2) val h2 = cache.getHabitByPosition(2)
val h3 = cache!!.getHabitByPosition(3) val h3 = cache.getHabitByPosition(3)
val h7 = cache!!.getHabitByPosition(7) val h7 = cache.getHabitByPosition(7)
cache!!.reorder(2, 7) cache.reorder(2, 7)
assertThat(cache!!.getHabitByPosition(2), IsEqual.equalTo(h3)) assertThat(cache.getHabitByPosition(2), equalTo(h3))
assertThat(cache!!.getHabitByPosition(7), IsEqual.equalTo(h2)) assertThat(cache.getHabitByPosition(7), equalTo(h2))
assertThat(cache!!.getHabitByPosition(6), IsEqual.equalTo(h7)) assertThat(cache.getHabitByPosition(6), equalTo(h7))
Mockito.verify(listener)!!.onItemMoved(2, 7) verify(listener).onItemMoved(2, 7)
Mockito.verifyNoMoreInteractions(listener) verifyNoMoreInteractions(listener)
} }
@Test @Test
@ -129,26 +128,25 @@ class HabitCardListCacheTest : BaseUnitTest() {
val h2 = habitList.getByPosition(2) val h2 = habitList.getByPosition(2)
val h3 = habitList.getByPosition(3) val h3 = habitList.getByPosition(3)
val h7 = habitList.getByPosition(7) val h7 = habitList.getByPosition(7)
assertThat(cache!!.getHabitByPosition(2), IsEqual.equalTo(h2)) assertThat(cache.getHabitByPosition(2), equalTo(h2))
assertThat(cache!!.getHabitByPosition(7), IsEqual.equalTo(h7)) assertThat(cache.getHabitByPosition(7), equalTo(h7))
Mockito.reset(listener) reset(listener)
habitList.reorder(h2, h7) habitList.reorder(h2, h7)
cache!!.refreshAllHabits() cache.refreshAllHabits()
assertThat(cache!!.getHabitByPosition(2), IsEqual.equalTo(h3)) assertThat(cache.getHabitByPosition(2), equalTo(h3))
assertThat(cache!!.getHabitByPosition(7), IsEqual.equalTo(h2)) assertThat(cache.getHabitByPosition(7), equalTo(h2))
assertThat(cache!!.getHabitByPosition(6), IsEqual.equalTo(h7)) assertThat(cache.getHabitByPosition(6), equalTo(h7))
Mockito.verify(listener)!!.onItemMoved(3, 2) verify(listener).onItemMoved(3, 2)
Mockito.verify(listener)!!.onItemMoved(4, 3) verify(listener).onItemMoved(4, 3)
Mockito.verify(listener)!!.onItemMoved(5, 4) verify(listener).onItemMoved(5, 4)
Mockito.verify(listener)!!.onItemMoved(6, 5) verify(listener).onItemMoved(6, 5)
Mockito.verify(listener)!!.onItemMoved(7, 6) verify(listener).onItemMoved(7, 6)
Mockito.verify(listener)!!.onRefreshFinished() verify(listener).onRefreshFinished()
Mockito.verifyNoMoreInteractions(listener) verifyNoMoreInteractions(listener)
} }
private fun removeHabitAt(position: Int) { private fun removeHabitAt(position: Int) {
val h = habitList.getByPosition(position) val h = habitList.getByPosition(position)
assertNotNull(h)
habitList.remove(h) habitList.remove(h)
} }
} }

@ -18,9 +18,12 @@
*/ */
package org.isoron.uhabits.core.ui.screens.habits.list package org.isoron.uhabits.core.ui.screens.habits.list
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertNull import junit.framework.Assert.assertNull
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import junit.framework.TestCase
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo import org.hamcrest.Matchers.equalTo
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
@ -29,42 +32,41 @@ import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday
import org.junit.Test import org.junit.Test
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito
class HintListTest : BaseUnitTest() { class HintListTest : BaseUnitTest() {
private var hintList: HintList? = null private lateinit var hintList: HintList
private lateinit var hints: Array<String> private lateinit var hints: Array<String>
@Mock @Mock
private val prefs: Preferences? = null private val prefs: Preferences = mock()
private var today: Timestamp? = null private lateinit var today: Timestamp
private var yesterday: Timestamp? = null private lateinit var yesterday: Timestamp
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
today = getToday() today = getToday()
yesterday = today!!.minus(1) yesterday = today.minus(1)
hints = arrayOf("hint1", "hint2", "hint3") hints = arrayOf("hint1", "hint2", "hint3")
hintList = HintList(prefs!!, hints) hintList = HintList(prefs, hints)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun pop() { fun pop() {
Mockito.`when`(prefs!!.lastHintNumber).thenReturn(-1) whenever(prefs.lastHintNumber).thenReturn(-1)
assertThat(hintList!!.pop(), equalTo("hint1")) assertThat(hintList.pop(), equalTo("hint1"))
Mockito.verify(prefs).updateLastHint(0, today) verify(prefs).updateLastHint(0, today)
Mockito.`when`(prefs.lastHintNumber).thenReturn(2) whenever(prefs.lastHintNumber).thenReturn(2)
assertNull(hintList!!.pop()) assertNull(hintList.pop())
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun shouldShow() { fun shouldShow() {
Mockito.`when`(prefs!!.lastHintTimestamp).thenReturn(today) whenever(prefs.lastHintTimestamp).thenReturn(today)
TestCase.assertFalse(hintList!!.shouldShow()) assertFalse(hintList.shouldShow())
Mockito.`when`(prefs.lastHintTimestamp).thenReturn(yesterday) whenever(prefs.lastHintTimestamp).thenReturn(yesterday)
assertTrue(hintList!!.shouldShow()) assertTrue(hintList.shouldShow())
} }
} }

@ -18,11 +18,18 @@
*/ */
package org.isoron.uhabits.core.ui.screens.habits.list package org.isoron.uhabits.core.ui.screens.habits.list
import com.nhaarman.mockitokotlin2.KArgumentCaptor
import com.nhaarman.mockitokotlin2.argumentCaptor
import com.nhaarman.mockitokotlin2.clearInvocations
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual.equalTo
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@ -31,32 +38,23 @@ import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday
import org.isoron.uhabits.core.utils.DateUtils.Companion.getTodayWithOffset import org.isoron.uhabits.core.utils.DateUtils.Companion.getTodayWithOffset
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
import java.io.IOException import java.io.IOException
import java.nio.file.Files import java.nio.file.Files
class ListHabitsBehaviorTest : BaseUnitTest() { class ListHabitsBehaviorTest : BaseUnitTest() {
@Mock private val dirFinder: ListHabitsBehavior.DirFinder = mock()
private val dirFinder: ListHabitsBehavior.DirFinder? = null
@Mock private val prefs: Preferences = mock()
private val prefs: Preferences? = null private lateinit var behavior: ListHabitsBehavior
private var behavior: ListHabitsBehavior? = null
@Mock private val screen: ListHabitsBehavior.Screen = mock()
private val screen: ListHabitsBehavior.Screen? = null private lateinit var habit1: Habit
private var habit1: Habit? = null private lateinit var habit2: Habit
private var habit2: Habit? = null
@Captor var picker: KArgumentCaptor<ListHabitsBehavior.NumberPickerCallback> = argumentCaptor()
var picker: ArgumentCaptor<ListHabitsBehavior.NumberPickerCallback>? = null
@Mock private val bugReporter: ListHabitsBehavior.BugReporter = mock()
private val bugReporter: ListHabitsBehavior.BugReporter? = null
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
@ -64,47 +62,37 @@ class ListHabitsBehaviorTest : BaseUnitTest() {
super.setUp() super.setUp()
habit1 = fixtures.createShortHabit() habit1 = fixtures.createShortHabit()
habit2 = fixtures.createNumericalHabit() habit2 = fixtures.createNumericalHabit()
habitList.add(habit1!!) habitList.add(habit1)
habitList.add(habit2!!) habitList.add(habit2)
Mockito.clearInvocations(habitList) clearInvocations(habitList)
behavior = ListHabitsBehavior( behavior = ListHabitsBehavior(
habitList, habitList,
dirFinder!!, dirFinder,
taskRunner, taskRunner,
screen!!, screen,
commandRunner, commandRunner,
prefs!!, prefs,
bugReporter!! bugReporter
) )
} }
@Test @Test
fun testOnEdit() { fun testOnEdit() {
behavior!!.onEdit(habit2!!, getToday()) behavior.onEdit(habit2, getToday())
Mockito.verify(screen)!!.showNumberPicker( verify(screen).showNumberPicker(eq(0.1), eq("miles"), picker.capture())
ArgumentMatchers.eq(0.1), picker.lastValue.onNumberPicked(100.0)
ArgumentMatchers.eq("miles"),
picker!!.capture()
)
picker!!.value.onNumberPicked(100.0)
val today = getTodayWithOffset() val today = getTodayWithOffset()
assertThat( assertThat(habit2.computedEntries.get(today).value, equalTo(100000))
habit2!!.computedEntries.get(today).value,
CoreMatchers.equalTo(100000)
)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testOnExportCSV() { fun testOnExportCSV() {
val outputDir = Files.createTempDirectory("CSV").toFile() val outputDir = Files.createTempDirectory("CSV").toFile()
Mockito.`when`(dirFinder!!.csvOutputDir).thenReturn(outputDir) whenever(dirFinder.csvOutputDir).thenReturn(outputDir)
behavior!!.onExportCSV() behavior.onExportCSV()
Mockito.verify(screen)!!.showSendFileScreen(ArgumentMatchers.any()) verify(screen).showSendFileScreen(ArgumentMatchers.any())
assertThat( assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1))
FileUtils.listFiles(outputDir, null, false).size,
CoreMatchers.equalTo(1)
)
FileUtils.deleteDirectory(outputDir) FileUtils.deleteDirectory(outputDir)
} }
@ -113,69 +101,66 @@ class ListHabitsBehaviorTest : BaseUnitTest() {
fun testOnExportCSV_fail() { fun testOnExportCSV_fail() {
val outputDir = Files.createTempDirectory("CSV").toFile() val outputDir = Files.createTempDirectory("CSV").toFile()
outputDir.setWritable(false) outputDir.setWritable(false)
Mockito.`when`(dirFinder!!.csvOutputDir).thenReturn(outputDir) whenever(dirFinder.csvOutputDir).thenReturn(outputDir)
behavior!!.onExportCSV() behavior.onExportCSV()
Mockito.verify(screen)!!.showMessage(ListHabitsBehavior.Message.COULD_NOT_EXPORT) verify(screen).showMessage(ListHabitsBehavior.Message.COULD_NOT_EXPORT)
assertTrue(outputDir.delete()) assertTrue(outputDir.delete())
} }
@Test @Test
fun testOnHabitClick() { fun testOnHabitClick() {
behavior!!.onClickHabit(habit1!!) behavior.onClickHabit(habit1)
Mockito.verify(screen)!!.showHabitScreen( verify(screen).showHabitScreen(habit1)
habit1!!
)
} }
@Test @Test
fun testOnHabitReorder() { fun testOnHabitReorder() {
val from = habit1 val from = habit1
val to = habit2 val to = habit2
behavior!!.onReorderHabit(from!!, to!!) behavior.onReorderHabit(from, to)
Mockito.verify(habitList)!!.reorder(from, to) verify(habitList).reorder(from, to)
} }
@Test @Test
fun testOnRepairDB() { fun testOnRepairDB() {
behavior!!.onRepairDB() behavior.onRepairDB()
Mockito.verify(habitList)!!.repair() verify(habitList).repair()
Mockito.verify(screen)!!.showMessage(ListHabitsBehavior.Message.DATABASE_REPAIRED) verify(screen).showMessage(ListHabitsBehavior.Message.DATABASE_REPAIRED)
} }
@Test @Test
@Throws(IOException::class) @Throws(IOException::class)
fun testOnSendBugReport() { fun testOnSendBugReport() {
Mockito.`when`(bugReporter!!.bugReport).thenReturn("hello") whenever(bugReporter.bugReport).thenReturn("hello")
behavior!!.onSendBugReport() behavior.onSendBugReport()
Mockito.verify(bugReporter).dumpBugReportToFile() verify(bugReporter).dumpBugReportToFile()
Mockito.verify(screen)!!.showSendBugReportToDeveloperScreen("hello") verify(screen).showSendBugReportToDeveloperScreen("hello")
Mockito.`when`(bugReporter.bugReport).thenThrow(IOException()) whenever(bugReporter.bugReport).thenThrow(IOException())
behavior!!.onSendBugReport() behavior.onSendBugReport()
Mockito.verify(screen)!! verify(screen).showMessage(ListHabitsBehavior.Message.COULD_NOT_GENERATE_BUG_REPORT)
.showMessage(ListHabitsBehavior.Message.COULD_NOT_GENERATE_BUG_REPORT)
} }
@Test @Test
fun testOnStartup_firstLaunch() { fun testOnStartup_firstLaunch() {
val today = getToday() val today = getToday()
Mockito.`when`(prefs!!.isFirstRun).thenReturn(true) whenever(prefs.isFirstRun).thenReturn(true)
behavior!!.onStartup() behavior.onStartup()
Mockito.verify(prefs).isFirstRun = false verify(prefs).isFirstRun = false
Mockito.verify(prefs).updateLastHint(-1, today) verify(prefs).updateLastHint(-1, today)
Mockito.verify(screen)!!.showIntroScreen() verify(screen).showIntroScreen()
} }
@Test @Test
fun testOnStartup_notFirstLaunch() { fun testOnStartup_notFirstLaunch() {
Mockito.`when`(prefs!!.isFirstRun).thenReturn(false) whenever(prefs.isFirstRun).thenReturn(false)
behavior!!.onStartup() behavior.onStartup()
Mockito.verify(prefs).incrementLaunchCount() verify(prefs).incrementLaunchCount()
} }
@Test @Test
fun testOnToggle() { fun testOnToggle() {
assertTrue(habit1!!.isCompletedToday()) assertTrue(habit1.isCompletedToday())
behavior!!.onToggle(habit1!!, getToday(), Entry.NO) behavior.onToggle(habit1, getToday(), Entry.NO)
assertFalse(habit1!!.isCompletedToday()) assertFalse(habit1.isCompletedToday())
} }
} }

@ -18,7 +18,16 @@
*/ */
package org.isoron.uhabits.core.ui.screens.habits.list package org.isoron.uhabits.core.ui.screens.habits.list
import junit.framework.TestCase import com.nhaarman.mockitokotlin2.KArgumentCaptor
import com.nhaarman.mockitokotlin2.argumentCaptor
import com.nhaarman.mockitokotlin2.clearInvocations
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
import com.nhaarman.mockitokotlin2.whenever
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo import org.hamcrest.Matchers.equalTo
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
@ -27,196 +36,144 @@ import org.isoron.uhabits.core.models.HabitMatcher
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.ui.ThemeSwitcher import org.isoron.uhabits.core.ui.ThemeSwitcher
import org.junit.Test import org.junit.Test
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
class ListHabitsMenuBehaviorTest : BaseUnitTest() { class ListHabitsMenuBehaviorTest : BaseUnitTest() {
private var behavior: ListHabitsMenuBehavior? = null private lateinit var behavior: ListHabitsMenuBehavior
@Mock private val screen: ListHabitsMenuBehavior.Screen = mock()
private val screen: ListHabitsMenuBehavior.Screen? = null
@Mock private val adapter: ListHabitsMenuBehavior.Adapter = mock()
private val adapter: ListHabitsMenuBehavior.Adapter? = null
@Mock private val prefs: Preferences = mock()
private val prefs: Preferences? = null
@Mock private val themeSwitcher: ThemeSwitcher = mock()
private val themeSwitcher: ThemeSwitcher? = null
@Captor private val matcherCaptor: KArgumentCaptor<HabitMatcher> = argumentCaptor()
private val matcherCaptor: ArgumentCaptor<HabitMatcher>? = null
@Captor private val orderCaptor: KArgumentCaptor<HabitList.Order> = argumentCaptor()
private val orderCaptor: ArgumentCaptor<HabitList.Order>? = null
@Captor private val secondaryOrderCaptor: KArgumentCaptor<HabitList.Order> = argumentCaptor()
private val secondaryOrderCaptor: ArgumentCaptor<HabitList.Order>? = null
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
behavior = ListHabitsMenuBehavior(screen!!, adapter!!, prefs!!, themeSwitcher!!) behavior = ListHabitsMenuBehavior(screen, adapter, prefs, themeSwitcher)
Mockito.clearInvocations(adapter) clearInvocations(adapter)
} }
@Test @Test
fun testInitialFilter() { fun testInitialFilter() {
Mockito.`when`(prefs!!.showArchived).thenReturn(true) whenever(prefs.showArchived).thenReturn(true)
Mockito.`when`(prefs.showCompleted).thenReturn(true) whenever(prefs.showCompleted).thenReturn(true)
behavior = ListHabitsMenuBehavior(screen!!, adapter!!, prefs, themeSwitcher!!) behavior = ListHabitsMenuBehavior(screen, adapter, prefs, themeSwitcher)
Mockito.verify(adapter).setFilter( verify(adapter).setFilter(matcherCaptor.capture())
matcherCaptor!!.capture() verify(adapter).refresh()
) verifyNoMoreInteractions(adapter)
Mockito.verify(adapter).refresh() clearInvocations(adapter)
Mockito.verifyNoMoreInteractions(adapter) assertTrue(matcherCaptor.lastValue.isArchivedAllowed)
Mockito.clearInvocations(adapter) assertTrue(matcherCaptor.lastValue.isCompletedAllowed)
TestCase.assertTrue(matcherCaptor.value.isArchivedAllowed) whenever(prefs.showArchived).thenReturn(false)
TestCase.assertTrue(matcherCaptor.value.isCompletedAllowed) whenever(prefs.showCompleted).thenReturn(false)
Mockito.`when`(prefs.showArchived).thenReturn(false)
Mockito.`when`(prefs.showCompleted).thenReturn(false)
behavior = ListHabitsMenuBehavior(screen, adapter, prefs, themeSwitcher) behavior = ListHabitsMenuBehavior(screen, adapter, prefs, themeSwitcher)
Mockito.verify(adapter).setFilter( verify(adapter).setFilter(matcherCaptor.capture())
matcherCaptor.capture() verify(adapter).refresh()
) verifyNoMoreInteractions(adapter)
Mockito.verify(adapter).refresh() assertFalse(matcherCaptor.lastValue.isArchivedAllowed)
Mockito.verifyNoMoreInteractions(adapter) assertFalse(matcherCaptor.lastValue.isCompletedAllowed)
TestCase.assertFalse(matcherCaptor.value.isArchivedAllowed)
TestCase.assertFalse(matcherCaptor.value.isCompletedAllowed)
} }
// @Test
// public void testOnCreateHabit()
// {
// behavior.onCreateHabit();
// verify(screen).showCreateHabitScreen();
// }
@Test @Test
fun testOnSortByColor() { fun testOnSortByColor() {
behavior!!.onSortByColor() behavior.onSortByColor()
Mockito.verify(adapter)!!.primaryOrder = orderCaptor!!.capture() verify(adapter).primaryOrder = orderCaptor.capture()
assertThat( assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_COLOR_ASC))
orderCaptor.value,
equalTo(HabitList.Order.BY_COLOR_ASC)
)
} }
@Test @Test
fun testOnSortManually() { fun testOnSortManually() {
behavior!!.onSortByManually() behavior.onSortByManually()
Mockito.verify(adapter)!!.primaryOrder = orderCaptor!!.capture() verify(adapter).primaryOrder = orderCaptor.capture()
assertThat( assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_POSITION))
orderCaptor.value,
equalTo(HabitList.Order.BY_POSITION)
)
} }
@Test @Test
fun testOnSortScore() { fun testOnSortScore() {
behavior!!.onSortByScore() behavior.onSortByScore()
Mockito.verify(adapter)!!.primaryOrder = orderCaptor!!.capture() verify(adapter).primaryOrder = orderCaptor.capture()
assertThat( assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_SCORE_DESC))
orderCaptor.value,
equalTo(HabitList.Order.BY_SCORE_DESC)
)
} }
@Test @Test
fun testOnSortName() { fun testOnSortName() {
behavior!!.onSortByName() behavior.onSortByName()
Mockito.verify(adapter)!!.primaryOrder = orderCaptor!!.capture() verify(adapter).primaryOrder = orderCaptor.capture()
assertThat( assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_NAME_ASC))
orderCaptor.value,
equalTo(HabitList.Order.BY_NAME_ASC)
)
} }
@Test @Test
fun testOnSortStatus() { fun testOnSortStatus() {
Mockito.`when`(adapter!!.primaryOrder).thenReturn(HabitList.Order.BY_NAME_ASC) whenever(adapter.primaryOrder).thenReturn(HabitList.Order.BY_NAME_ASC)
behavior!!.onSortByStatus() behavior.onSortByStatus()
Mockito.verify(adapter).primaryOrder = orderCaptor!!.capture() verify(adapter).primaryOrder = orderCaptor.capture()
Mockito.verify(adapter).setSecondaryOrder( verify(adapter).setSecondaryOrder(secondaryOrderCaptor.capture())
secondaryOrderCaptor!!.capture() assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_STATUS_ASC))
) assertThat(secondaryOrderCaptor.lastValue, equalTo(HabitList.Order.BY_NAME_ASC))
assertThat(
orderCaptor.value,
equalTo(HabitList.Order.BY_STATUS_ASC)
)
assertThat(
secondaryOrderCaptor.value,
equalTo(HabitList.Order.BY_NAME_ASC)
)
} }
@Test @Test
fun testOnSortStatusToggle() { fun testOnSortStatusToggle() {
Mockito.`when`(adapter!!.primaryOrder).thenReturn(HabitList.Order.BY_STATUS_ASC) whenever(adapter.primaryOrder).thenReturn(HabitList.Order.BY_STATUS_ASC)
behavior!!.onSortByStatus() behavior.onSortByStatus()
Mockito.verify(adapter).primaryOrder = orderCaptor!!.capture() verify(adapter).primaryOrder = orderCaptor.capture()
Mockito.verify(adapter, Mockito.never()).setSecondaryOrder(ArgumentMatchers.any()) verify(adapter, never()).setSecondaryOrder(ArgumentMatchers.any())
assertThat( assertThat(orderCaptor.lastValue, equalTo(HabitList.Order.BY_STATUS_DESC))
orderCaptor.value,
equalTo(HabitList.Order.BY_STATUS_DESC)
)
} }
@Test @Test
fun testOnToggleShowArchived() { fun testOnToggleShowArchived() {
behavior!!.onToggleShowArchived() behavior.onToggleShowArchived()
Mockito.verify(adapter)!!.setFilter( verify(adapter).setFilter(matcherCaptor.capture())
matcherCaptor!!.capture() assertTrue(matcherCaptor.lastValue.isArchivedAllowed)
) clearInvocations(adapter)
TestCase.assertTrue(matcherCaptor.value.isArchivedAllowed) behavior.onToggleShowArchived()
Mockito.clearInvocations(adapter) verify(adapter).setFilter(matcherCaptor.capture())
behavior!!.onToggleShowArchived() assertFalse(matcherCaptor.lastValue.isArchivedAllowed)
Mockito.verify(adapter)!!.setFilter(
matcherCaptor.capture()
)
TestCase.assertFalse(matcherCaptor.value.isArchivedAllowed)
} }
@Test @Test
fun testOnToggleShowCompleted() { fun testOnToggleShowCompleted() {
behavior!!.onToggleShowCompleted() behavior.onToggleShowCompleted()
Mockito.verify(adapter)!!.setFilter( verify(adapter).setFilter(matcherCaptor.capture())
matcherCaptor!!.capture() assertTrue(matcherCaptor.lastValue.isCompletedAllowed)
) clearInvocations(adapter)
TestCase.assertTrue(matcherCaptor.value.isCompletedAllowed) behavior.onToggleShowCompleted()
Mockito.clearInvocations(adapter) verify(adapter).setFilter(matcherCaptor.capture())
behavior!!.onToggleShowCompleted() assertFalse(matcherCaptor.lastValue.isCompletedAllowed)
Mockito.verify(adapter)!!.setFilter(
matcherCaptor.capture()
)
TestCase.assertFalse(matcherCaptor.value.isCompletedAllowed)
} }
@Test @Test
fun testOnViewAbout() { fun testOnViewAbout() {
behavior!!.onViewAbout() behavior.onViewAbout()
Mockito.verify(screen)!!.showAboutScreen() verify(screen).showAboutScreen()
} }
@Test @Test
fun testOnViewFAQ() { fun testOnViewFAQ() {
behavior!!.onViewFAQ() behavior.onViewFAQ()
Mockito.verify(screen)!!.showFAQScreen() verify(screen).showFAQScreen()
} }
@Test @Test
fun testOnViewSettings() { fun testOnViewSettings() {
behavior!!.onViewSettings() behavior.onViewSettings()
Mockito.verify(screen)!!.showSettingsScreen() verify(screen).showSettingsScreen()
} }
@Test @Test
fun testOnToggleNightMode() { fun testOnToggleNightMode() {
behavior!!.onToggleNightMode() behavior.onToggleNightMode()
Mockito.verify(themeSwitcher)!!.toggleNightMode() verify(themeSwitcher).toggleNightMode()
Mockito.verify(screen)!!.applyTheme() verify(screen).applyTheme()
} }
} }

@ -18,7 +18,15 @@
*/ */
package org.isoron.uhabits.core.ui.screens.habits.list package org.isoron.uhabits.core.ui.screens.habits.list
import junit.framework.TestCase import com.nhaarman.mockitokotlin2.KArgumentCaptor
import com.nhaarman.mockitokotlin2.argumentCaptor
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertNull
import junit.framework.Assert.assertTrue
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo import org.hamcrest.Matchers.equalTo
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
@ -27,126 +35,113 @@ import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback import org.isoron.uhabits.core.ui.callbacks.OnColorPickedCallback
import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback import org.isoron.uhabits.core.ui.callbacks.OnConfirmedCallback
import org.junit.Test import org.junit.Test
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
class ListHabitsSelectionMenuBehaviorTest : BaseUnitTest() { class ListHabitsSelectionMenuBehaviorTest : BaseUnitTest() {
@Mock private val screen: ListHabitsSelectionMenuBehavior.Screen = mock()
private val screen: ListHabitsSelectionMenuBehavior.Screen? = null
@Mock private val adapter: ListHabitsSelectionMenuBehavior.Adapter = mock()
private val adapter: ListHabitsSelectionMenuBehavior.Adapter? = null private lateinit var behavior: ListHabitsSelectionMenuBehavior
private var behavior: ListHabitsSelectionMenuBehavior? = null private lateinit var habit1: Habit
private var habit1: Habit? = null private lateinit var habit2: Habit
private var habit2: Habit? = null private lateinit var habit3: Habit
private var habit3: Habit? = null
@Captor private val colorPickerCallback: KArgumentCaptor<OnColorPickedCallback> = argumentCaptor()
private val colorPickerCallback: ArgumentCaptor<OnColorPickedCallback>? = null
@Captor private val deleteCallback: KArgumentCaptor<OnConfirmedCallback> = argumentCaptor()
private val deleteCallback: ArgumentCaptor<OnConfirmedCallback>? = null
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun canArchive() { fun canArchive() {
Mockito.`when`(adapter!!.selected).thenReturn(listOf(habit1, habit2)) whenever(adapter.selected).thenReturn(listOf(habit1, habit2))
TestCase.assertFalse(behavior!!.canArchive()) assertFalse(behavior.canArchive())
Mockito.`when`(adapter.selected).thenReturn(listOf(habit2, habit3)) whenever(adapter.selected).thenReturn(listOf(habit2, habit3))
TestCase.assertTrue(behavior!!.canArchive()) assertTrue(behavior.canArchive())
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun canEdit() { fun canEdit() {
Mockito.`when`(adapter!!.selected).thenReturn(listOf(habit1)) whenever(adapter.selected).thenReturn(listOf(habit1))
TestCase.assertTrue(behavior!!.canEdit()) assertTrue(behavior.canEdit())
Mockito.`when`(adapter.selected).thenReturn(listOf(habit1, habit2)) whenever(adapter.selected).thenReturn(listOf(habit1, habit2))
TestCase.assertFalse(behavior!!.canEdit()) assertFalse(behavior.canEdit())
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun canUnarchive() { fun canUnarchive() {
Mockito.`when`(adapter!!.selected).thenReturn(listOf(habit1, habit2)) whenever(adapter.selected).thenReturn(listOf(habit1, habit2))
TestCase.assertFalse(behavior!!.canUnarchive()) assertFalse(behavior.canUnarchive())
Mockito.`when`(adapter.selected).thenReturn(listOf(habit1)) whenever(adapter.selected).thenReturn(listOf(habit1))
TestCase.assertTrue(behavior!!.canUnarchive()) assertTrue(behavior.canUnarchive())
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun onArchiveHabits() { fun onArchiveHabits() {
TestCase.assertFalse(habit2!!.isArchived) assertFalse(habit2.isArchived)
Mockito.`when`(adapter!!.selected).thenReturn(listOf(habit2)) whenever(adapter.selected).thenReturn(listOf(habit2))
behavior!!.onArchiveHabits() behavior.onArchiveHabits()
TestCase.assertTrue(habit2!!.isArchived) assertTrue(habit2.isArchived)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun onChangeColor() { fun onChangeColor() {
assertThat(habit1!!.color, equalTo(PaletteColor(8))) assertThat(habit1.color, equalTo(PaletteColor(8)))
assertThat(habit2!!.color, equalTo(PaletteColor(8))) assertThat(habit2.color, equalTo(PaletteColor(8)))
Mockito.`when`(adapter!!.selected).thenReturn(listOf(habit1, habit2)) whenever(adapter.selected).thenReturn(listOf(habit1, habit2))
behavior!!.onChangeColor() behavior.onChangeColor()
Mockito.verify(screen)!! verify(screen)
.showColorPicker(ArgumentMatchers.eq(PaletteColor(8)), colorPickerCallback!!.capture()) .showColorPicker(eq(PaletteColor(8)), colorPickerCallback.capture())
colorPickerCallback.value.onColorPicked(PaletteColor(30)) colorPickerCallback.lastValue.onColorPicked(PaletteColor(30))
assertThat(habit1!!.color, equalTo(PaletteColor(30))) assertThat(habit1.color, equalTo(PaletteColor(30)))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun onDeleteHabits() { fun onDeleteHabits() {
val id = habit1!!.id val id = habit1.id!!
TestCase.assertNotNull(id) habitList.getById(id)!!
TestCase.assertNotNull(habitList.getById(id!!)) whenever(adapter.selected).thenReturn(listOf(habit1))
Mockito.`when`(adapter!!.selected).thenReturn(listOf(habit1)) behavior.onDeleteHabits()
behavior!!.onDeleteHabits() verify(screen).showDeleteConfirmationScreen(deleteCallback.capture(), eq(1))
Mockito.verify(screen)!!.showDeleteConfirmationScreen( deleteCallback.lastValue.onConfirmed()
deleteCallback!!.capture(), assertNull(habitList.getById(id))
ArgumentMatchers.eq(1)
)
deleteCallback.value.onConfirmed()
TestCase.assertNull(habitList.getById(id))
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun onEditHabits() { fun onEditHabits() {
val selected: List<Habit> = listOf(habit1!!, habit2!!) val selected: List<Habit> = listOf(habit1, habit2)
Mockito.`when`(adapter!!.selected).thenReturn(selected) whenever(adapter.selected).thenReturn(selected)
behavior!!.onEditHabits() behavior.onEditHabits()
Mockito.verify(screen)!!.showEditHabitsScreen(selected) verify(screen).showEditHabitsScreen(selected)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun onUnarchiveHabits() { fun onUnarchiveHabits() {
TestCase.assertTrue(habit1!!.isArchived) assertTrue(habit1.isArchived)
Mockito.`when`(adapter!!.selected).thenReturn(listOf(habit1)) whenever(adapter.selected).thenReturn(listOf(habit1))
behavior!!.onUnarchiveHabits() behavior.onUnarchiveHabits()
TestCase.assertFalse(habit1!!.isArchived) assertFalse(habit1.isArchived)
} }
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
habit1 = fixtures.createShortHabit() habit1 = fixtures.createShortHabit()
habit1!!.isArchived = true habit1.isArchived = true
habit2 = fixtures.createShortHabit() habit2 = fixtures.createShortHabit()
habit3 = fixtures.createShortHabit() habit3 = fixtures.createShortHabit()
habitList.add(habit1!!) habitList.add(habit1)
habitList.add(habit2!!) habitList.add(habit2)
habitList.add(habit3!!) habitList.add(habit3)
behavior = ListHabitsSelectionMenuBehavior( behavior = ListHabitsSelectionMenuBehavior(
habitList, habitList,
screen!!, screen,
adapter!!, adapter,
commandRunner commandRunner
) )
} }

@ -18,13 +18,15 @@
*/ */
package org.isoron.uhabits.core.ui.screens.habits.show package org.isoron.uhabits.core.ui.screens.habits.show
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.junit.Test import org.junit.Test
import org.mockito.Mockito
import java.nio.file.Files import java.nio.file.Files
class ShowHabitMenuPresenterTest : BaseUnitTest() { class ShowHabitMenuPresenterTest : BaseUnitTest() {
@ -32,11 +34,12 @@ class ShowHabitMenuPresenterTest : BaseUnitTest() {
private lateinit var screen: ShowHabitMenuPresenter.Screen private lateinit var screen: ShowHabitMenuPresenter.Screen
private lateinit var habit: Habit private lateinit var habit: Habit
private lateinit var menu: ShowHabitMenuPresenter private lateinit var menu: ShowHabitMenuPresenter
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
system = Mockito.mock(ShowHabitMenuPresenter.System::class.java) system = mock()
screen = Mockito.mock(ShowHabitMenuPresenter.Screen::class.java) screen = mock()
habit = fixtures.createShortHabit() habit = fixtures.createShortHabit()
menu = ShowHabitMenuPresenter( menu = ShowHabitMenuPresenter(
commandRunner, commandRunner,
@ -51,16 +54,16 @@ class ShowHabitMenuPresenterTest : BaseUnitTest() {
@Test @Test
fun testOnEditHabit() { fun testOnEditHabit() {
menu.onEditHabit() menu.onEditHabit()
Mockito.verify(screen)!!.showEditHabitScreen(habit) verify(screen).showEditHabitScreen(habit)
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testOnExport() { fun testOnExport() {
val outputDir = Files.createTempDirectory("CSV").toFile() val outputDir = Files.createTempDirectory("CSV").toFile()
Mockito.`when`(system.getCSVOutputDir()).thenReturn(outputDir) whenever(system.getCSVOutputDir()).thenReturn(outputDir)
menu.onExportCSV() menu.onExportCSV()
assertThat(FileUtils.listFiles(outputDir, null, false).size, CoreMatchers.equalTo(1)) assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1))
FileUtils.deleteDirectory(outputDir) FileUtils.deleteDirectory(outputDir)
} }
} }

@ -18,8 +18,12 @@
*/ */
package org.isoron.uhabits.core.ui.widgets package org.isoron.uhabits.core.ui.widgets
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.reset
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
import com.nhaarman.mockitokotlin2.whenever
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.commands.CreateRepetitionCommand import org.isoron.uhabits.core.commands.CreateRepetitionCommand
import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Entry.Companion.nextToggleValueWithSkip import org.isoron.uhabits.core.models.Entry.Companion.nextToggleValueWithSkip
@ -31,44 +35,43 @@ import org.isoron.uhabits.core.ui.NotificationTray
import org.isoron.uhabits.core.utils.DateUtils.Companion.getTodayWithOffset import org.isoron.uhabits.core.utils.DateUtils.Companion.getTodayWithOffset
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.Mockito
class WidgetBehaviorTest : BaseUnitTest() { class WidgetBehaviorTest : BaseUnitTest() {
private lateinit var notificationTray: NotificationTray private lateinit var notificationTray: NotificationTray
private lateinit var preferences: Preferences private lateinit var preferences: Preferences
private lateinit var behavior: WidgetBehavior private lateinit var behavior: WidgetBehavior
private var habit: Habit? = null private lateinit var habit: Habit
private var today: Timestamp? = null private lateinit var today: Timestamp
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
habit = fixtures.createEmptyHabit() habit = fixtures.createEmptyHabit()
commandRunner = Mockito.mock(CommandRunner::class.java) commandRunner = mock()
notificationTray = Mockito.mock(NotificationTray::class.java) notificationTray = mock()
preferences = Mockito.mock(Preferences::class.java) preferences = mock()
behavior = WidgetBehavior(habitList, commandRunner, notificationTray, preferences) behavior = WidgetBehavior(habitList, commandRunner, notificationTray, preferences)
today = getTodayWithOffset() today = getTodayWithOffset()
} }
@Test @Test
fun testOnAddRepetition() { fun testOnAddRepetition() {
behavior.onAddRepetition(habit!!, today) behavior.onAddRepetition(habit, today)
Mockito.verify(commandRunner)!!.run( verify(commandRunner).run(
CreateRepetitionCommand(habitList, habit!!, today!!, Entry.YES_MANUAL) CreateRepetitionCommand(habitList, habit, today, Entry.YES_MANUAL)
) )
Mockito.verify(notificationTray)!!.cancel(habit!!) verify(notificationTray).cancel(habit)
Mockito.verifyZeroInteractions(preferences) verifyZeroInteractions(preferences)
} }
@Test @Test
fun testOnRemoveRepetition() { fun testOnRemoveRepetition() {
behavior.onRemoveRepetition(habit!!, today) behavior.onRemoveRepetition(habit, today)
Mockito.verify(commandRunner)!!.run( verify(commandRunner).run(
CreateRepetitionCommand(habitList, habit!!, today!!, Entry.NO) CreateRepetitionCommand(habitList, habit, today, Entry.NO)
) )
Mockito.verify(notificationTray)!!.cancel(habit!!) verify(notificationTray).cancel(habit)
Mockito.verifyZeroInteractions(preferences) verifyZeroInteractions(preferences)
} }
@Test @Test
@ -81,46 +84,46 @@ class WidgetBehaviorTest : BaseUnitTest() {
Entry.SKIP Entry.SKIP
) )
) { ) {
Mockito.`when`(preferences.isSkipEnabled).thenReturn(skipEnabled) whenever(preferences.isSkipEnabled).thenReturn(skipEnabled)
val nextValue: Int = if (skipEnabled) nextToggleValueWithSkip(currentValue) else nextToggleValueWithoutSkip( val nextValue: Int = if (skipEnabled) nextToggleValueWithSkip(currentValue) else nextToggleValueWithoutSkip(
currentValue currentValue
) )
habit!!.originalEntries.add(Entry(today!!, currentValue)) habit.originalEntries.add(Entry(today, currentValue))
behavior.onToggleRepetition(habit!!, today) behavior.onToggleRepetition(habit, today)
Mockito.verify(preferences)!!.isSkipEnabled verify(preferences).isSkipEnabled
Mockito.verify(commandRunner)!!.run( verify(commandRunner).run(
CreateRepetitionCommand(habitList, habit!!, today!!, nextValue) CreateRepetitionCommand(habitList, habit, today, nextValue)
) )
Mockito.verify(notificationTray)!!.cancel( verify(notificationTray).cancel(
habit!! habit
) )
Mockito.reset(preferences, commandRunner, notificationTray) reset(preferences, commandRunner, notificationTray)
} }
} }
@Test @Test
fun testOnIncrement() { fun testOnIncrement() {
habit = fixtures.createNumericalHabit() habit = fixtures.createNumericalHabit()
habit!!.originalEntries.add(Entry(today!!, 500)) habit.originalEntries.add(Entry(today, 500))
habit!!.recompute() habit.recompute()
behavior.onIncrement(habit!!, today!!, 100) behavior.onIncrement(habit, today, 100)
Mockito.verify(commandRunner)!!.run( verify(commandRunner).run(
CreateRepetitionCommand(habitList, habit!!, today!!, 600) CreateRepetitionCommand(habitList, habit, today, 600)
) )
Mockito.verify(notificationTray)!!.cancel(habit!!) verify(notificationTray).cancel(habit)
Mockito.verifyZeroInteractions(preferences) verifyZeroInteractions(preferences)
} }
@Test @Test
fun testOnDecrement() { fun testOnDecrement() {
habit = fixtures.createNumericalHabit() habit = fixtures.createNumericalHabit()
habit!!.originalEntries.add(Entry(today!!, 500)) habit.originalEntries.add(Entry(today, 500))
habit!!.recompute() habit.recompute()
behavior.onDecrement(habit!!, today!!, 100) behavior.onDecrement(habit, today, 100)
Mockito.verify(commandRunner)!!.run( verify(commandRunner).run(
CreateRepetitionCommand(habitList, habit!!, today!!, 400) CreateRepetitionCommand(habitList, habit, today, 400)
) )
Mockito.verify(notificationTray)!!.cancel(habit!!) verify(notificationTray).cancel(habit)
Mockito.verifyZeroInteractions(preferences) verifyZeroInteractions(preferences)
} }
} }

@ -19,8 +19,8 @@
package org.isoron.uhabits.core.utils package org.isoron.uhabits.core.utils
import junit.framework.Assert.assertEquals import junit.framework.Assert.assertEquals
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual.equalTo
import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.utils.DateUtils.Companion.applyTimezone import org.isoron.uhabits.core.utils.DateUtils.Companion.applyTimezone
@ -42,6 +42,7 @@ import java.util.TimeZone
class DateUtilsTest : BaseUnitTest() { class DateUtilsTest : BaseUnitTest() {
var firstWeekday = Calendar.SUNDAY var firstWeekday = Calendar.SUNDAY
@Before @Before
@Throws(Exception::class) @Throws(Exception::class)
override fun setUp() { override fun setUp() {
@ -54,7 +55,7 @@ class DateUtilsTest : BaseUnitTest() {
val timestamp = unixTime(2015, Calendar.DECEMBER, 31) val timestamp = unixTime(2015, Calendar.DECEMBER, 31)
val date = Timestamp(timestamp).toCalendar() val date = Timestamp(timestamp).toCalendar()
val formatted = formatHeaderDate(date) val formatted = formatHeaderDate(date)
assertThat(formatted, CoreMatchers.equalTo("Thu\n31")) assertThat(formatted, equalTo("Thu\n31"))
} }
@Test @Test
@ -64,24 +65,24 @@ class DateUtilsTest : BaseUnitTest() {
var t0 = unixTime(2015, Calendar.JANUARY, 11) var t0 = unixTime(2015, Calendar.JANUARY, 11)
var t1 = unixTime(2015, Calendar.JANUARY, 16) var t1 = unixTime(2015, Calendar.JANUARY, 16)
var t2 = unixTime(2015, Calendar.JANUARY, 17) var t2 = unixTime(2015, Calendar.JANUARY, 17)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
expected = unixTime(2015, Calendar.JANUARY, 18) expected = unixTime(2015, Calendar.JANUARY, 18)
t0 = unixTime(2015, Calendar.JANUARY, 18) t0 = unixTime(2015, Calendar.JANUARY, 18)
t1 = unixTime(2015, Calendar.JANUARY, 19) t1 = unixTime(2015, Calendar.JANUARY, 19)
t2 = unixTime(2015, Calendar.JANUARY, 24) t2 = unixTime(2015, Calendar.JANUARY, 24)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
firstWeekday = Calendar.WEDNESDAY firstWeekday = Calendar.WEDNESDAY
expected = unixTime(2015, Calendar.JANUARY, 7) expected = unixTime(2015, Calendar.JANUARY, 7)
t0 = unixTime(2015, Calendar.JANUARY, 7) t0 = unixTime(2015, Calendar.JANUARY, 7)
t1 = unixTime(2015, Calendar.JANUARY, 9) t1 = unixTime(2015, Calendar.JANUARY, 9)
t2 = unixTime(2015, Calendar.JANUARY, 13) t2 = unixTime(2015, Calendar.JANUARY, 13)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
} }
@Test @Test
@ -91,16 +92,16 @@ class DateUtilsTest : BaseUnitTest() {
var t1 = unixTime(2016, Calendar.JUNE, 15) var t1 = unixTime(2016, Calendar.JUNE, 15)
var t2 = unixTime(2016, Calendar.JUNE, 20) var t2 = unixTime(2016, Calendar.JUNE, 20)
val field = DateUtils.TruncateField.MONTH val field = DateUtils.TruncateField.MONTH
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
expected = unixTime(2016, Calendar.DECEMBER, 1) expected = unixTime(2016, Calendar.DECEMBER, 1)
t0 = unixTime(2016, Calendar.DECEMBER, 1) t0 = unixTime(2016, Calendar.DECEMBER, 1)
t1 = unixTime(2016, Calendar.DECEMBER, 15) t1 = unixTime(2016, Calendar.DECEMBER, 15)
t2 = unixTime(2016, Calendar.DECEMBER, 31) t2 = unixTime(2016, Calendar.DECEMBER, 31)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
} }
@Test @Test
@ -110,16 +111,16 @@ class DateUtilsTest : BaseUnitTest() {
var t0 = unixTime(2016, Calendar.JANUARY, 20) var t0 = unixTime(2016, Calendar.JANUARY, 20)
var t1 = unixTime(2016, Calendar.FEBRUARY, 15) var t1 = unixTime(2016, Calendar.FEBRUARY, 15)
var t2 = unixTime(2016, Calendar.MARCH, 30) var t2 = unixTime(2016, Calendar.MARCH, 30)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
expected = unixTime(2016, Calendar.APRIL, 1) expected = unixTime(2016, Calendar.APRIL, 1)
t0 = unixTime(2016, Calendar.APRIL, 1) t0 = unixTime(2016, Calendar.APRIL, 1)
t1 = unixTime(2016, Calendar.MAY, 30) t1 = unixTime(2016, Calendar.MAY, 30)
t2 = unixTime(2016, Calendar.JUNE, 20) t2 = unixTime(2016, Calendar.JUNE, 20)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
} }
@Test @Test
@ -129,16 +130,16 @@ class DateUtilsTest : BaseUnitTest() {
var t0 = unixTime(2016, Calendar.JANUARY, 1) var t0 = unixTime(2016, Calendar.JANUARY, 1)
var t1 = unixTime(2016, Calendar.FEBRUARY, 25) var t1 = unixTime(2016, Calendar.FEBRUARY, 25)
var t2 = unixTime(2016, Calendar.DECEMBER, 31) var t2 = unixTime(2016, Calendar.DECEMBER, 31)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
expected = unixTime(2017, Calendar.JANUARY, 1) expected = unixTime(2017, Calendar.JANUARY, 1)
t0 = unixTime(2017, Calendar.JANUARY, 1) t0 = unixTime(2017, Calendar.JANUARY, 1)
t1 = unixTime(2017, Calendar.MAY, 30) t1 = unixTime(2017, Calendar.MAY, 30)
t2 = unixTime(2017, Calendar.DECEMBER, 31) t2 = unixTime(2017, Calendar.DECEMBER, 31)
assertThat(truncate(field, t0, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t0, firstWeekday), equalTo(expected))
assertThat(truncate(field, t1, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t1, firstWeekday), equalTo(expected))
assertThat(truncate(field, t2, firstWeekday), CoreMatchers.equalTo(expected)) assertThat(truncate(field, t2, firstWeekday), equalTo(expected))
} }
@Test @Test
@ -146,41 +147,33 @@ class DateUtilsTest : BaseUnitTest() {
fun testMillisecondsUntilTomorrow() { fun testMillisecondsUntilTomorrow() {
setFixedTimeZone(TimeZone.getTimeZone("GMT")) setFixedTimeZone(TimeZone.getTimeZone("GMT"))
setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 1, 23, 59)) setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 1, 23, 59))
assertThat( assertThat(millisecondsUntilTomorrowWithOffset(), equalTo(DateUtils.MINUTE_LENGTH))
millisecondsUntilTomorrowWithOffset(),
CoreMatchers.equalTo(
DateUtils.MINUTE_LENGTH
)
)
setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 1, 20, 0)) setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 1, 20, 0))
assertThat( assertThat(
millisecondsUntilTomorrowWithOffset(), millisecondsUntilTomorrowWithOffset(),
CoreMatchers.equalTo(4 * DateUtils.HOUR_LENGTH) equalTo(4 * DateUtils.HOUR_LENGTH)
) )
setStartDayOffset(3, 30) setStartDayOffset(3, 30)
setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 1, 23, 59)) setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 1, 23, 59))
assertThat( assertThat(
millisecondsUntilTomorrowWithOffset(), millisecondsUntilTomorrowWithOffset(),
CoreMatchers.equalTo(3 * DateUtils.HOUR_LENGTH + 31 * DateUtils.MINUTE_LENGTH) equalTo(3 * DateUtils.HOUR_LENGTH + 31 * DateUtils.MINUTE_LENGTH)
) )
setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 2, 1, 0)) setFixedLocalTime(unixTime(2017, Calendar.JANUARY, 2, 1, 0))
assertThat( assertThat(
millisecondsUntilTomorrowWithOffset(), millisecondsUntilTomorrowWithOffset(),
CoreMatchers.equalTo(2 * DateUtils.HOUR_LENGTH + 30 * DateUtils.MINUTE_LENGTH) equalTo(2 * DateUtils.HOUR_LENGTH + 30 * DateUtils.MINUTE_LENGTH)
) )
} }
@Test @Test
@Throws(Exception::class) @Throws(Exception::class)
fun testGetTodayWithOffset() { fun testGetTodayWithOffset() {
assertThat( assertThat(getTodayWithOffset(), equalTo(Timestamp(FIXED_LOCAL_TIME)))
getTodayWithOffset(),
CoreMatchers.equalTo(Timestamp(FIXED_LOCAL_TIME))
)
setStartDayOffset(9, 0) setStartDayOffset(9, 0)
assertThat( assertThat(
getTodayWithOffset(), getTodayWithOffset(),
CoreMatchers.equalTo(Timestamp(FIXED_LOCAL_TIME - DateUtils.DAY_LENGTH)) equalTo(Timestamp(FIXED_LOCAL_TIME - DateUtils.DAY_LENGTH))
) )
} }
@ -190,12 +183,12 @@ class DateUtilsTest : BaseUnitTest() {
val timestamp = unixTime(2020, Calendar.SEPTEMBER, 3) val timestamp = unixTime(2020, Calendar.SEPTEMBER, 3)
assertThat( assertThat(
getStartOfDayWithOffset(timestamp + DateUtils.HOUR_LENGTH), getStartOfDayWithOffset(timestamp + DateUtils.HOUR_LENGTH),
CoreMatchers.equalTo(timestamp) equalTo(timestamp)
) )
setStartDayOffset(3, 30) setStartDayOffset(3, 30)
assertThat( assertThat(
getStartOfDayWithOffset(timestamp + 3 * DateUtils.HOUR_LENGTH + 29 * DateUtils.MINUTE_LENGTH), getStartOfDayWithOffset(timestamp + 3 * DateUtils.HOUR_LENGTH + 29 * DateUtils.MINUTE_LENGTH),
CoreMatchers.equalTo(timestamp - DateUtils.DAY_LENGTH) equalTo(timestamp - DateUtils.DAY_LENGTH)
) )
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save