diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt index 9dade3a8c..a7a1b2759 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/HabitsActivityTestComponent.kt @@ -19,6 +19,7 @@ package org.isoron.uhabits +import com.nhaarman.mockitokotlin2.mock import dagger.Component import dagger.Module import dagger.Provides @@ -34,11 +35,11 @@ import org.isoron.uhabits.inject.ActivityScope import org.isoron.uhabits.inject.HabitModule import org.isoron.uhabits.inject.HabitsActivityModule import org.isoron.uhabits.inject.HabitsApplicationComponent -import org.mockito.Mockito.mock @Module class TestModule { - @Provides fun listHabitsBehavior(): ListHabitsBehavior = mock(ListHabitsBehavior::class.java) + @Provides + fun listHabitsBehavior(): ListHabitsBehavior = mock() } @ActivityScope diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.java b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.java deleted file mode 100644 index c4246c615..000000000 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.activities.habits.list.views; - -import androidx.test.filters.*; -import androidx.test.runner.*; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.isoron.uhabits.*; -import org.isoron.uhabits.core.preferences.*; -import org.isoron.uhabits.core.utils.*; -import org.junit.*; -import org.junit.runner.*; - -import static org.mockito.Mockito.*; - -@RunWith(AndroidJUnit4.class) -@MediumTest -public class HeaderViewTest extends BaseViewTest -{ - public static final String PATH = "habits/list/HeaderView/"; - - private HeaderView view; - - private Preferences prefs; - - private MidnightTimer midnightTimer; - - @Override - @Before - public void setUp() - { - super.setUp(); - prefs = mock(Preferences.class); - midnightTimer = mock(MidnightTimer.class); - view = new HeaderView(targetContext, prefs, midnightTimer); - view.setButtonCount(5); - measureView(view, dpToPixels(600), dpToPixels(48)); - } - - @Test - public void testRender() throws Exception - { - when(prefs.isCheckmarkSequenceReversed()).thenReturn(false); - - assertRenders(view, PATH + "render.png"); - - verify(prefs).isCheckmarkSequenceReversed(); - verifyNoMoreInteractions(prefs); - } - - @Test - public void testRender_reverse() throws Exception - { - when(prefs.isCheckmarkSequenceReversed()).thenReturn(true); - - assertRenders(view, PATH + "render_reverse.png"); - - verify(prefs).isCheckmarkSequenceReversed(); - verifyNoMoreInteractions(prefs); - } -} \ No newline at end of file diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.kt new file mode 100644 index 000000000..ccfebd949 --- /dev/null +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HeaderViewTest.kt @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016-2021 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package org.isoron.uhabits.activities.habits.list.views + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.MediumTest +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.whenever +import org.isoron.uhabits.BaseViewTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito + +@RunWith(AndroidJUnit4::class) +@MediumTest +class HeaderViewTest : BaseViewTest() { + private var view: HeaderView? = null + + @Before + override fun setUp() { + super.setUp() + prefs = mock() + view = HeaderView(targetContext, prefs, mock()) + view!!.buttonCount = 5 + measureView(view, dpToPixels(600), dpToPixels(48)) + } + + @Test + @Throws(Exception::class) + fun testRender() { + Mockito.`when`(prefs.isCheckmarkSequenceReversed).thenReturn(false) + assertRenders(view, PATH + "render.png") + Mockito.verify(prefs).isCheckmarkSequenceReversed + Mockito.verifyNoMoreInteractions(prefs) + } + + @Test + @Throws(Exception::class) + fun testRender_reverse() { + doReturn(true).whenever(prefs).isCheckmarkSequenceReversed + // Mockito.`when`(prefs.isCheckmarkSequenceReversed).thenReturn(true) + assertRenders(view, PATH + "render_reverse.png") + Mockito.verify(prefs).isCheckmarkSequenceReversed + Mockito.verifyNoMoreInteractions(prefs) + } + + companion object { + const val PATH = "habits/list/HeaderView/" + } +} diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.java b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.java deleted file mode 100644 index 09291948f..000000000 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.activities.habits.list.views; - -import androidx.test.filters.*; -import androidx.test.runner.*; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.isoron.uhabits.*; -import org.isoron.uhabits.core.ui.screens.habits.list.*; -import org.junit.*; -import org.junit.runner.*; - -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.*; -import static org.mockito.Mockito.*; - -@RunWith(AndroidJUnit4.class) -@MediumTest -public class HintViewTest extends BaseViewTest -{ - public static final String PATH = "habits/list/HintView/"; - - private HintView view; - - private HintList list; - - @Before - @Override - public void setUp() - { - super.setUp(); - - list = mock(HintList.class); - view = new HintView(targetContext, list); - measureView(view, 400, 200); - - String text = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; - - when(list.shouldShow()).thenReturn(true); - when(list.pop()).thenReturn(text); - - view.showNext(); - skipAnimation(view); - } - - @Test - public void testRender() throws Exception - { - assertRenders(view, PATH + "render.png"); - } - - @Test - public void testClick() throws Exception - { - assertThat(view.getAlpha(), equalTo(1f)); - view.performClick(); - skipAnimation(view); - assertThat(view.getAlpha(), equalTo(0f)); - } -} diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.kt new file mode 100644 index 000000000..6685acc9e --- /dev/null +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/HintViewTest.kt @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2016-2021 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package org.isoron.uhabits.activities.habits.list.views + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.MediumTest +import com.nhaarman.mockitokotlin2.doReturn +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.whenever +import org.hamcrest.CoreMatchers +import org.hamcrest.MatcherAssert +import org.isoron.uhabits.BaseViewTest +import org.isoron.uhabits.core.ui.screens.habits.list.HintList +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@MediumTest +class HintViewTest : BaseViewTest() { + private lateinit var view: HintView + private lateinit var list: HintList + @Before + override fun setUp() { + super.setUp() + list = mock() + view = HintView(targetContext, list) + measureView(view, 400f, 200f) + val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + doReturn(true).whenever(list).shouldShow() + doReturn(text).whenever(list).pop() + // Mockito.`when`(list.shouldShow()).thenReturn(true) + // Mockito.`when`(list.pop()).thenReturn(text) + view.showNext() + skipAnimation(view) + } + + @Test + @Throws(Exception::class) + fun testRender() { + assertRenders(view, PATH + "render.png") + } + + @Test + @Throws(Exception::class) + fun testClick() { + MatcherAssert.assertThat(view.alpha, CoreMatchers.equalTo(1f)) + view.performClick() + skipAnimation(view) + MatcherAssert.assertThat(view.alpha, CoreMatchers.equalTo(0f)) + } + + companion object { + const val PATH = "habits/list/HintView/" + } +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/StreakChart.java b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/StreakChart.java index 16961c335..1ebf43202 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/StreakChart.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/StreakChart.java @@ -19,19 +19,27 @@ package org.isoron.uhabits.activities.common.views; -import android.content.*; -import android.graphics.*; -import android.util.*; -import android.view.*; -import android.view.ViewGroup.*; - -import org.isoron.uhabits.*; -import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.core.utils.*; -import org.isoron.uhabits.utils.*; - -import java.text.*; -import java.util.*; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup.LayoutParams; + +import org.isoron.uhabits.R; +import org.isoron.uhabits.core.models.Streak; +import org.isoron.uhabits.core.models.Timestamp; +import org.isoron.uhabits.core.utils.DateUtils; +import org.isoron.uhabits.utils.StyledResources; + +import java.text.DateFormat; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.TimeZone; import static android.view.View.MeasureSpec.*; import static org.isoron.uhabits.utils.InterfaceUtils.*; @@ -98,7 +106,7 @@ public class StreakChart extends View public void populateWithRandomData() { Timestamp start = DateUtils.getToday(); - LinkedList streaks = new LinkedList<>(); + List streaks = new LinkedList<>(); for (int i = 0; i < 10; i++) { diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListAdapter.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListAdapter.kt index c968a98db..8e3a7d96d 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListAdapter.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListAdapter.kt @@ -121,7 +121,7 @@ class HabitCardListAdapter @Inject constructor( val score = cache.getScore(habit!!.id!!) val checkmarks = cache.getCheckmarks(habit.id!!) val selected = selected.contains(habit) - listView!!.bindCardView(holder, habit, score, checkmarks!!, selected) + listView!!.bindCardView(holder, habit, score, checkmarks, selected) } override fun onViewAttachedToWindow(holder: HabitCardViewHolder) { diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt index 3f8a76995..7fc3a6142 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/database/Repository.kt @@ -168,6 +168,7 @@ class Repository( get() { val fields: MutableList> = ArrayList() for (f in klass.declaredFields) { + f.isAccessible = true for (annotation in f.annotations) { if (annotation !is Column) continue fields.add(ImmutablePair(f, annotation)) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt index 43fd47a24..3923cf87a 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt @@ -29,7 +29,7 @@ import java.util.LinkedList import kotlin.math.max import kotlin.math.min -class Preferences(private val storage: Storage) { +open class Preferences(private val storage: Storage) { private val listeners: MutableList private var shouldReverseCheckmarks: Boolean? = null fun addListener(listener: Listener) { @@ -86,7 +86,7 @@ class Preferences(private val storage: Storage) { } val lastHintNumber: Int get() = storage.getInt("last_hint_number", -1) - val lastHintTimestamp: Timestamp? + open val lastHintTimestamp: Timestamp? get() { val unixTime = storage.getLong("last_hint_timestamp", -1) return if (unixTime < 0) null else Timestamp(unixTime) @@ -171,7 +171,7 @@ class Preferences(private val storage: Storage) { return storage.getBoolean("pref_led_notifications", false) } - var isCheckmarkSequenceReversed: Boolean + open var isCheckmarkSequenceReversed: Boolean get() { if (shouldReverseCheckmarks == null) shouldReverseCheckmarks = storage.getBoolean("pref_checkmark_reverse_order", false) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt index fec0d4099..f15f4fced 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt @@ -25,7 +25,7 @@ import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday * Provides a list of hints to be shown at the application startup, and takes * care of deciding when a new hint should be shown. */ -class HintList(private val prefs: Preferences, private val hints: Array) { +open class HintList(private val prefs: Preferences, private val hints: Array) { /** * Returns a new hint to be shown to the user. * @@ -36,7 +36,7 @@ class HintList(private val prefs: Preferences, private val hints: Array) * * @return the next hint to be shown, or null if none */ - fun pop(): String? { + open fun pop(): String? { val next = prefs.lastHintNumber + 1 if (next >= hints.size) return null prefs.updateLastHint(next, getToday()) @@ -48,7 +48,7 @@ class HintList(private val prefs: Preferences, private val hints: Array) * * @return true if hint should be shown, false otherwise */ - fun shouldShow(): Boolean { + open fun shouldShow(): Boolean { val today = getToday() val lastHintTimestamp = prefs.lastHintTimestamp return lastHintTimestamp?.isOlderThan(today) == true diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt index 8144a8fb3..0c52a8dcd 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt @@ -33,7 +33,7 @@ import java.io.IOException import java.util.LinkedList import javax.inject.Inject -class ListHabitsBehavior @Inject constructor( +open class ListHabitsBehavior @Inject constructor( private val habitList: HabitList, private val dirFinder: DirFinder, private val taskRunner: TaskRunner, diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/RepositoryTest.java b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/RepositoryTest.java deleted file mode 100644 index 232ad25ff..000000000 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/RepositoryTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.core.database; - -import org.apache.commons.lang3.builder.*; -import org.isoron.uhabits.core.*; -import org.junit.*; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - - -public class RepositoryTest extends BaseUnitTest -{ - private Repository repository; - - private Database db; - - @Before - @Override - public void setUp() throws Exception - { - super.setUp(); - this.db = BaseUnitTest.Companion.buildMemoryDatabase(); - repository = new Repository<>(ThingRecord.class, db); - - db.execute("drop table if exists tests"); - db.execute("create table tests(" + - "id integer not null primary key autoincrement, " + - "color_number integer not null, score float not null, " + - "name string)"); - } - - @Test - public void testFind() throws Exception - { - db.execute("insert into tests(id, color_number, name, score) " + - "values (10, 20, 'hello', 8.0)"); - - ThingRecord record = repository.find(10L); - - assertNotNull(record); - assertThat(record.id, equalTo(10L)); - assertThat(record.color, equalTo(20)); - assertThat(record.name, equalTo("hello")); - assertThat(record.score, equalTo(8.0)); - } - - @Test - public void testSave_withId() throws Exception - { - ThingRecord record = new ThingRecord(); - record.id = 50L; - record.color = 10; - record.name = "hello"; - record.score = 5.0; - repository.save(record); - assertThat(record, equalTo(repository.find(50L))); - - record.name = "world"; - record.score = 128.0; - repository.save(record); - assertThat(record, equalTo(repository.find(50L))); - } - - @Test - public void testSave_withNull() throws Exception - { - ThingRecord record = new ThingRecord(); - record.color = 50; - record.name = null; - record.score = 12.0; - repository.save(record); - - ThingRecord retrieved = repository.find(record.id); - assertNotNull(retrieved); - assertNull(retrieved.name); - assertThat(record, equalTo(retrieved)); - } - - @Test - public void testSave_withoutId() throws Exception - { - ThingRecord r1 = new ThingRecord(); - r1.color = 10; - r1.name = "hello"; - r1.score = 16.0; - repository.save(r1); - - ThingRecord r2 = new ThingRecord(); - r2.color = 20; - r2.name = "world"; - r2.score = 2.0; - repository.save(r2); - - assertThat(r1.id, equalTo(1L)); - assertThat(r2.id, equalTo(2L)); - } - - @Test - public void testRemove() throws Exception - { - ThingRecord rec1 = new ThingRecord(); - rec1.color = 10; - rec1.name = "hello"; - rec1.score = 16.0; - repository.save(rec1); - - ThingRecord rec2 = new ThingRecord(); - rec2.color = 20; - rec2.name = "world"; - rec2.score = 32.0; - repository.save(rec2); - - long id = rec1.id; - assertThat(rec1, equalTo(repository.find(id))); - assertThat(rec2, equalTo(repository.find(rec2.id))); - - repository.remove(rec1); - assertThat(rec1.id, equalTo(null)); - assertNull(repository.find(id)); - assertThat(rec2, equalTo(repository.find(rec2.id))); - - repository.remove(rec1); // should have no effect - assertNull(repository.find(id)); - } -} - -@Table(name = "tests") -class ThingRecord -{ - @Column - public Long id; - - @Column - public String name; - - @Column(name = "color_number") - public Integer color; - - @Column - public Double score; - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - - if (o == null || getClass() != o.getClass()) return false; - - ThingRecord record = (ThingRecord) o; - - return new EqualsBuilder() - .append(id, record.id) - .append(name, record.name) - .append(color, record.color) - .isEquals(); - } - - @Override - public int hashCode() - { - return new HashCodeBuilder(17, 37) - .append(id) - .append(name) - .append(color) - .toHashCode(); - } - - @Override - public String toString() - { - return new ToStringBuilder(this) - .append("id", id) - .append("name", name) - .append("color", color) - .toString(); - } -} diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/RepositoryTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/RepositoryTest.kt new file mode 100644 index 000000000..1d13b98a0 --- /dev/null +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/RepositoryTest.kt @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2016-2021 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package org.isoron.uhabits.core.database + +import org.hamcrest.MatcherAssert +import org.hamcrest.core.IsEqual +import org.isoron.uhabits.core.BaseUnitTest +import org.junit.Assert +import org.junit.Before +import org.junit.Test + +class RepositoryTest : BaseUnitTest() { + private var repository: Repository? = null + private var db: Database? = null + @Before + @Throws(Exception::class) + override fun setUp() { + super.setUp() + db = buildMemoryDatabase() + repository = Repository(ThingRecord::class.java, db!!) + db!!.execute("drop table if exists tests") + db!!.execute( + "create table tests(" + + "id integer not null primary key autoincrement, " + + "color_number integer not null, score float not null, " + + "name string)" + ) + } + + @Test + @Throws(Exception::class) + fun testFind() { + db!!.execute( + "insert into tests(id, color_number, name, score) " + + "values (10, 20, 'hello', 8.0)" + ) + val record = repository!!.find(10L) + Assert.assertNotNull(record) + MatcherAssert.assertThat(record!!.id, IsEqual.equalTo(10L)) + MatcherAssert.assertThat(record.color, IsEqual.equalTo(20)) + MatcherAssert.assertThat(record.name, IsEqual.equalTo("hello")) + MatcherAssert.assertThat(record.score, IsEqual.equalTo(8.0)) + } + + @Test + @Throws(Exception::class) + fun testSave_withId() { + val record = ThingRecord() + record.id = 50L + record.color = 10 + record.name = "hello" + record.score = 5.0 + repository!!.save(record) + MatcherAssert.assertThat( + record, + IsEqual.equalTo( + repository!!.find(50L) + ) + ) + record.name = "world" + record.score = 128.0 + repository!!.save(record) + MatcherAssert.assertThat( + record, + IsEqual.equalTo( + repository!!.find(50L) + ) + ) + } + + @Test + @Throws(Exception::class) + fun testSave_withNull() { + val record = ThingRecord() + record.color = 50 + record.name = null + record.score = 12.0 + repository!!.save(record) + val retrieved = repository!!.find(record.id!!) + Assert.assertNotNull(retrieved) + Assert.assertNull(retrieved!!.name) + MatcherAssert.assertThat(record, IsEqual.equalTo(retrieved)) + } + + @Test + @Throws(Exception::class) + fun testSave_withoutId() { + val r1 = ThingRecord() + r1.color = 10 + r1.name = "hello" + r1.score = 16.0 + repository!!.save(r1) + val r2 = ThingRecord() + r2.color = 20 + r2.name = "world" + r2.score = 2.0 + repository!!.save(r2) + MatcherAssert.assertThat(r1.id, IsEqual.equalTo(1L)) + MatcherAssert.assertThat(r2.id, IsEqual.equalTo(2L)) + } + + @Test + @Throws(Exception::class) + fun testRemove() { + val rec1 = ThingRecord() + rec1.color = 10 + rec1.name = "hello" + rec1.score = 16.0 + repository!!.save(rec1) + val rec2 = ThingRecord() + rec2.color = 20 + rec2.name = "world" + rec2.score = 32.0 + repository!!.save(rec2) + val id = rec1.id!! + MatcherAssert.assertThat( + rec1, + IsEqual.equalTo( + repository!!.find(id) + ) + ) + MatcherAssert.assertThat( + rec2, + IsEqual.equalTo( + repository!!.find(rec2.id!!) + ) + ) + repository!!.remove(rec1) + MatcherAssert.assertThat(rec1.id, IsEqual.equalTo(null)) + Assert.assertNull(repository!!.find(id)) + MatcherAssert.assertThat( + rec2, + IsEqual.equalTo( + repository!!.find(rec2.id!!) + ) + ) + repository!!.remove(rec1) // should have no effect + Assert.assertNull(repository!!.find(id)) + } +} diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/ThingRecord.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/ThingRecord.kt new file mode 100644 index 000000000..47c4eaaba --- /dev/null +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/ThingRecord.kt @@ -0,0 +1,46 @@ +package org.isoron.uhabits.core.database + +import org.apache.commons.lang3.builder.EqualsBuilder +import org.apache.commons.lang3.builder.HashCodeBuilder +import org.apache.commons.lang3.builder.ToStringBuilder + +@Table(name = "tests") +open class ThingRecord { + @field:Column + open var id: Long? = null + + @field:Column + open var name: String? = null + + @field:Column(name = "color_number") + open var color: Int? = null + + @field:Column + open var score: Double? = null + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || javaClass != other.javaClass) return false + val record = other as ThingRecord + return EqualsBuilder() + .append(id, record.id) + .append(name, record.name) + .append(color, record.color) + .isEquals + } + + override fun hashCode(): Int { + return HashCodeBuilder(17, 37) + .append(id) + .append(name) + .append(color) + .toHashCode() + } + + override fun toString(): String { + return ToStringBuilder(this) + .append("id", id) + .append("name", name) + .append("color", color) + .toString() + } +}