diff --git a/uhabits-android/release/output-metadata.json b/uhabits-android/release/output-metadata.json new file mode 100644 index 000000000..f725cdace --- /dev/null +++ b/uhabits-android/release/output-metadata.json @@ -0,0 +1,37 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "org.isoron.uhabits", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 20202, + "versionName": "2.2.2", + "outputFile": "uhabits-android-release.apk" + } + ], + "elementType": "File", + "baselineProfiles": [ + { + "minApi": 28, + "maxApi": 30, + "baselineProfiles": [ + "baselineProfiles/1/uhabits-android-release.dm" + ] + }, + { + "minApi": 31, + "maxApi": 2147483647, + "baselineProfiles": [ + "baselineProfiles/0/uhabits-android-release.dm" + ] + } + ], + "minSdkVersionForDexing": 28 +} \ No newline at end of file diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt index 91c21af9b..cf5055f90 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardListController.kt @@ -60,8 +60,10 @@ class HabitCardListController @Inject constructor( return } - val hgrFrom = adapter.getHabitGroup(from)!! - val hgrTo = adapter.getHabitGroup(to) ?: return + var hgrFrom = adapter.getHabitGroup(from)!! + if (hgrFrom.parent != null) hgrFrom = hgrFrom.parent!! + var hgrTo = adapter.getHabitGroup(to) ?: return + if (hgrTo.parent != null) hgrTo = hgrTo.parent!! adapter.performReorder(from, to) behavior.onReorderHabitGroup(hgrFrom, hgrTo) } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt index a11eed785..4faed3cda 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroup.kt @@ -115,7 +115,7 @@ data class HabitGroup( override fun equals(other: Any?): Boolean { if (this === other) return true - if (other !is Habit) return false + if (other !is HabitGroup) return false if (color != other.color) return false if (description != other.description) return false diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt index b1cc256ff..4f82e50fe 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/HabitGroupList.kt @@ -200,8 +200,6 @@ abstract class HabitGroupList : Iterable { "Name", "Question", "Description", - "NumRepetitions", - "Interval", "Color" ) val csv = CSVWriter(out) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt index 4fef8519c..45aa4567d 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitGroupList.kt @@ -45,10 +45,6 @@ class MemoryHabitGroupList : HabitGroupList { primaryOrder = parent.primaryOrder secondaryOrder = parent.secondaryOrder parent.observable.addListener { loadFromParent() } - for (hgr in parent.list) { - hgr.habitList.observable.addListener { loadFromParent() } - hgr.observable.notifyListeners() - } loadFromParent() } @@ -213,7 +209,8 @@ class MemoryHabitGroupList : HabitGroupList { list.add(filteredHgr) } } - resort() + primaryOrder = parent!!.primaryOrder + secondaryOrder = parent!!.secondaryOrder } @Synchronized @@ -221,7 +218,6 @@ class MemoryHabitGroupList : HabitGroupList { for (hgr in list) { hgr.habitList.primaryOrder = primaryOrder hgr.habitList.secondaryOrder = secondaryOrder - hgr.habitList.resort() } if (comparator != null) list.sortWith(comparator!!) observable.notifyListeners() diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.kt index 3a08b3048..a980762b1 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.kt @@ -242,6 +242,8 @@ class MemoryHabitList : HabitList { checkNotNull(parent) list.clear() for (h in parent!!) if (filter.matches(h)) list.add(h) + primaryOrder = parent!!.primaryOrder + secondaryOrder = parent!!.secondaryOrder resort() } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt index 0cb91d3d6..e33526710 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupList.kt @@ -146,14 +146,14 @@ class SQLiteHabitGroupList @Inject constructor(private val modelFactory: ModelFa if (toRecord == null) throw RuntimeException("habit not in database") if (toRecord.position!! < fromRecord.position!!) { repository.execSQL( - "update habits set position = position + 1 " + + "update habitgroups set position = position + 1 " + "where position >= ? and position < ?", toRecord.position!!, fromRecord.position!! ) } else { repository.execSQL( - "update habits set position = position - 1 " + + "update habitgroups set position = position - 1 " + "where position > ? and position <= ?", fromRecord.position!!, toRecord.position!! diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitGroupListTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitGroupListTest.kt new file mode 100644 index 000000000..9e8ed0de5 --- /dev/null +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitGroupListTest.kt @@ -0,0 +1,266 @@ +/* + * 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.models + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.CoreMatchers.not +import org.hamcrest.MatcherAssert.assertThat +import org.isoron.uhabits.core.BaseUnitTest +import org.junit.Assert.assertThrows +import org.junit.Test +import java.io.IOException +import java.io.StringWriter +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNull + +class HabitGroupListTest : BaseUnitTest() { + private lateinit var habitGroupArray: ArrayList + private lateinit var activeHabitGroups: HabitGroupList + private lateinit var reminderHabitGroups: HabitGroupList + + @Throws(Exception::class) + override fun setUp() { + super.setUp() + habitGroupArray = ArrayList() + for (i in 0..9) { + val hgr = groupFixtures.createEmptyHabitGroup() + habitGroupList.add(hgr) + habitGroupArray.add(hgr) + if (i % 3 == 0) hgr.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) + } + habitGroupArray[0].isArchived = true + habitGroupArray[1].isArchived = true + habitGroupArray[4].isArchived = true + habitGroupArray[7].isArchived = true + activeHabitGroups = habitGroupList.getFiltered(HabitMatcher()) + reminderHabitGroups = habitGroupList.getFiltered( + HabitMatcher( + isArchivedAllowed = true, + isReminderRequired = true + ) + ) + } + + @Test + fun testSize() { + assertThat(habitGroupList.size(), equalTo(10)) + assertThat(activeHabitGroups.size(), equalTo(6)) + assertThat(reminderHabitGroups.size(), equalTo(4)) + } + + @Test + fun testGetByPosition() { + assertThat(habitGroupList.getByPosition(0), equalTo(habitGroupArray[0])) + assertThat(habitGroupList.getByPosition(3), equalTo(habitGroupArray[3])) + assertThat(habitGroupList.getByPosition(9), equalTo(habitGroupArray[9])) + assertThat(activeHabitGroups.getByPosition(0), equalTo(habitGroupArray[2])) + assertThat(reminderHabitGroups.getByPosition(1), equalTo(habitGroupArray[3])) + } + + @Test + fun testGetById() { + val hgr1 = habitGroupArray[0] + val hgr2 = habitGroupList.getById(hgr1.id!!) + assertThat(hgr1, equalTo(hgr2)) + } + + @Test + fun testGetById_withInvalidId() { + assertNull(habitGroupList.getById(100L)) + } + + @Test + fun testOrdering() { + val hgr1 = groupFixtures.createEmptyHabitGroup("A Habit Group", PaletteColor(2), 1) + val hgr2 = groupFixtures.createEmptyHabitGroup("B Habit Group", PaletteColor(2), 3) + val hgr3 = groupFixtures.createEmptyHabitGroup("C Habit Group", PaletteColor(0), 0) + val hgr4 = groupFixtures.createEmptyHabitGroup("D Habit Group", PaletteColor(1), 2) + + val list = modelFactory.buildHabitGroupList().apply { + add(hgr3) + add(hgr1) + add(hgr4) + add(hgr2) + } + + list.primaryOrder = HabitList.Order.BY_POSITION + assertThat(list.getByPosition(0), equalTo(hgr3)) + assertThat(list.getByPosition(1), equalTo(hgr1)) + assertThat(list.getByPosition(2), equalTo(hgr4)) + assertThat(list.getByPosition(3), equalTo(hgr2)) + list.primaryOrder = HabitList.Order.BY_NAME_DESC + assertThat(list.getByPosition(0), equalTo(hgr4)) + assertThat(list.getByPosition(1), equalTo(hgr3)) + assertThat(list.getByPosition(2), equalTo(hgr2)) + assertThat(list.getByPosition(3), equalTo(hgr1)) + list.primaryOrder = HabitList.Order.BY_NAME_ASC + assertThat(list.getByPosition(0), equalTo(hgr1)) + assertThat(list.getByPosition(1), equalTo(hgr2)) + assertThat(list.getByPosition(2), equalTo(hgr3)) + assertThat(list.getByPosition(3), equalTo(hgr4)) + list.primaryOrder = HabitList.Order.BY_NAME_ASC + list.remove(hgr1) + list.add(hgr1) + assertThat(list.getByPosition(0), equalTo(hgr1)) + list.primaryOrder = HabitList.Order.BY_COLOR_ASC + list.secondaryOrder = HabitList.Order.BY_NAME_ASC + assertThat(list.getByPosition(0), equalTo(hgr3)) + assertThat(list.getByPosition(1), equalTo(hgr4)) + assertThat(list.getByPosition(2), equalTo(hgr1)) + assertThat(list.getByPosition(3), equalTo(hgr2)) + list.primaryOrder = HabitList.Order.BY_COLOR_DESC + list.secondaryOrder = HabitList.Order.BY_NAME_ASC + assertThat(list.getByPosition(0), equalTo(hgr1)) + assertThat(list.getByPosition(1), equalTo(hgr2)) + assertThat(list.getByPosition(2), equalTo(hgr4)) + assertThat(list.getByPosition(3), equalTo(hgr3)) + list.primaryOrder = HabitList.Order.BY_POSITION + assertThat(list.getByPosition(0), equalTo(hgr3)) + assertThat(list.getByPosition(1), equalTo(hgr1)) + assertThat(list.getByPosition(2), equalTo(hgr4)) + assertThat(list.getByPosition(3), equalTo(hgr2)) + } + + @Test + fun testReorder() { + val operations = + arrayOf(intArrayOf(5, 2), intArrayOf(3, 7), intArrayOf(4, 4), intArrayOf(8, 3)) + val expectedSequence = arrayOf( + intArrayOf(0, 1, 5, 2, 3, 4, 6, 7, 8, 9), + intArrayOf(0, 1, 5, 2, 4, 6, 7, 3, 8, 9), + intArrayOf(0, 1, 5, 2, 4, 6, 7, 3, 8, 9), + intArrayOf(0, 1, 5, 2, 4, 6, 7, 8, 3, 9) + ) + for (i in operations.indices) { + val fromHabitGroup = habitGroupArray[operations[i][0]] + val toHabitGroup = habitGroupArray[operations[i][1]] + habitGroupList.reorder(fromHabitGroup, toHabitGroup) + val actualSequence = IntArray(10) + for (j in 0..9) { + val hgr = habitGroupList.getByPosition(j) + assertThat(hgr.position, equalTo(j)) + actualSequence[j] = Math.toIntExact(hgr.id!!) + } + assertThat(actualSequence, equalTo(expectedSequence[i])) + } + assertThat(activeHabitGroups.indexOf(habitGroupArray[5]), equalTo(0)) + assertThat(activeHabitGroups.indexOf(habitGroupArray[2]), equalTo(1)) + } + + @Test + @Throws(Exception::class) + fun testReorder_withInvalidArguments() { + val hgr1 = habitGroupArray[0] + val hgr2 = groupFixtures.createEmptyHabitGroup() + assertThrows(IllegalArgumentException::class.java) { + habitGroupList.reorder(hgr1, hgr2) + } + } + + @Test + fun testOrder_inherit() { + habitGroupList.primaryOrder = HabitList.Order.BY_COLOR_ASC + val filteredList = habitGroupList.getFiltered( + HabitMatcher( + isArchivedAllowed = false, + isCompletedAllowed = false + ) + ) + assertEquals(filteredList.primaryOrder, HabitList.Order.BY_COLOR_ASC) + } + + @Test + @Throws(IOException::class) + fun testWriteCSV() { + val list = modelFactory.buildHabitGroupList() + val hgr1 = groupFixtures.createEmptyHabitGroup() + hgr1.name = "Meditate" + hgr1.question = "Did you meditate this morning?" + hgr1.description = "this is a test description" + hgr1.color = PaletteColor(3) + val hgr2 = groupFixtures.createEmptyHabitGroup() + hgr2.name = "Wake up early" + hgr2.question = "Did you wake up before 6am?" + hgr2.description = "" + hgr2.color = PaletteColor(5) + list.add(hgr1) + list.add(hgr2) + val expectedCSV = + """ + Position,Name,Question,Description,Color + 001,Meditate,Did you meditate this morning?,this is a test description,#FF8F00 + 002,Wake up early,Did you wake up before 6am?,,#AFB42B + + """.trimIndent() + val writer = StringWriter() + list.writeCSV(writer) + assertThat(writer.toString(), equalTo(expectedCSV)) + } + + @Test + @Throws(Exception::class) + fun testAdd() { + val hgr1 = groupFixtures.createEmptyHabitGroup() + assertFalse(hgr1.isArchived) + assertNull(hgr1.id) + assertThat(habitGroupList.indexOf(hgr1), equalTo(-1)) + habitGroupList.add(hgr1) + hgr1.id!! + assertThat(habitGroupList.indexOf(hgr1), not(equalTo(-1))) + assertThat(activeHabitGroups.indexOf(hgr1), not(equalTo(-1))) + } + + @Test + @Throws(Exception::class) + fun testAdd_withFilteredList() { + assertThrows(IllegalStateException::class.java) { + activeHabitGroups.add(groupFixtures.createEmptyHabitGroup()) + } + } + + @Test + @Throws(Exception::class) + fun testRemove_onFilteredList() { + assertThrows(IllegalStateException::class.java) { + activeHabitGroups.remove(groupFixtures.createEmptyHabitGroup()) + } + } + + @Test + @Throws(Exception::class) + fun testReorder_onFilteredList() { + val hgr1 = groupFixtures.createEmptyHabitGroup() + val hgr2 = groupFixtures.createEmptyHabitGroup() + assertThrows(IllegalStateException::class.java) { + activeHabitGroups.reorder(hgr1, hgr2) + } + } + + @Test + @Throws(Exception::class) + fun testReorder_onSortedList() { + habitGroupList.primaryOrder = HabitList.Order.BY_SCORE_DESC + val hgr1 = habitGroupArray[1] + val hgr2 = habitGroupArray[2] + assertThrows(IllegalStateException::class.java) { + habitGroupList.reorder(hgr1, hgr2) + } + } +} diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitGroupTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitGroupTest.kt index 1a5e1bd05..4a5ffdb28 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitGroupTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/HabitGroupTest.kt @@ -121,4 +121,31 @@ class HabitGroupTest : BaseUnitTest() { assertThat(hgr.id, equalTo(0L)) assertThat(hgr.uriString, equalTo("content://org.isoron.uhabits/habitgroup/0")) } + + @Test + @Throws(Exception::class) + fun testScores() { + val hgr = groupFixtures.createGroupWithNumericalHabits(numHabits = 2) + hgr.recompute() + val today = getToday() + val expectedScore = hgr.habitList.map { it.scores[today].value }.average() + assertEquals(expectedScore, hgr.scores[today].value) + } + + @Test + @Throws(Exception::class) + fun testStreaks() { + val hgr = groupFixtures.createGroupWithNumericalHabits(numHabits = 2) + hgr.recompute() + assertEquals(hgr.habitList.getByPosition(0).streaks.getBest(1), hgr.streaks.getBest(1)) + + val hgr2 = groupFixtures.createGroupWithEmptyHabits(numHabits = 2) + val h = hgr2.habitList.getByPosition(0) + h.originalEntries.add(Entry(getToday(), 2)) + h.originalEntries.add(Entry(getToday().minus(1), 2)) + val h2 = hgr2.habitList.getByPosition(1) + h2.originalEntries.add(Entry(getToday().minus(2), 2)) + hgr2.recompute() + assertEquals(0, hgr2.streaks.getBest(1).size) + } } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupListTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupListTest.kt new file mode 100644 index 000000000..9f1d45bdb --- /dev/null +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitGroupListTest.kt @@ -0,0 +1,188 @@ +/* + * 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.models.sqlite + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.isoron.uhabits.core.BaseUnitTest +import org.isoron.uhabits.core.database.Database +import org.isoron.uhabits.core.database.Repository +import org.isoron.uhabits.core.models.HabitGroup +import org.isoron.uhabits.core.models.HabitGroupList +import org.isoron.uhabits.core.models.HabitList +import org.isoron.uhabits.core.models.HabitMatcher +import org.isoron.uhabits.core.models.ModelObservable +import org.isoron.uhabits.core.models.Reminder +import org.isoron.uhabits.core.models.WeekdayList +import org.isoron.uhabits.core.models.sqlite.records.HabitGroupRecord +import org.isoron.uhabits.core.test.HabitGroupFixtures +import org.junit.Assert.assertThrows +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import kotlin.test.assertNull + +class SQLiteHabitGroupListTest : BaseUnitTest() { + private lateinit var repository: Repository + private var listener: ModelObservable.Listener = mock() + private lateinit var habitGroupsArray: ArrayList + private lateinit var activeHabitGroups: HabitGroupList + private lateinit var reminderHabitGroups: HabitGroupList + + @Throws(Exception::class) + override fun setUp() { + super.setUp() + val db: Database = buildMemoryDatabase() + modelFactory = SQLModelFactory(db) + habitGroupList = SQLiteHabitGroupList(modelFactory) + groupFixtures = HabitGroupFixtures(modelFactory, habitList, habitGroupList) + repository = Repository(HabitGroupRecord::class.java, db) + habitGroupsArray = ArrayList() + for (i in 0..9) { + val hgr = groupFixtures.createEmptyHabitGroup() + hgr.name = "habit group " + (i + 1) + habitGroupList.update(hgr) + habitGroupsArray.add(hgr) + if (i % 3 == 0) hgr.reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) + } + habitGroupsArray[0].isArchived = true + habitGroupsArray[1].isArchived = true + habitGroupsArray[4].isArchived = true + habitGroupsArray[7].isArchived = true + habitGroupList.update(habitGroupsArray) + activeHabitGroups = habitGroupList.getFiltered(HabitMatcher()) + reminderHabitGroups = habitGroupList.getFiltered( + HabitMatcher( + isArchivedAllowed = true, + isReminderRequired = true + ) + ) + habitGroupList.observable.addListener(listener) + } + + @Throws(Exception::class) + override fun tearDown() { + habitGroupList.observable.removeListener(listener) + super.tearDown() + } + + @Test + fun testAdd_withDuplicate() { + val hgr = modelFactory.buildHabitGroup() + habitGroupList.add(hgr) + verify(listener).onModelChange() + assertThrows(IllegalArgumentException::class.java) { + habitGroupList.add(hgr) + } + } + + @Test + fun testAdd_withId() { + val hgr = modelFactory.buildHabitGroup() + hgr.name = "Hello world with id" + hgr.id = 12300L + habitGroupList.add(hgr) + assertThat(hgr.id, equalTo(11L)) + val record = repository.find(11L) + assertThat(record!!.name, equalTo(hgr.name)) + } + + @Test + fun testAdd_withoutId() { + val hgr = modelFactory.buildHabitGroup() + hgr.name = "Hello world" + assertNull(hgr.id) + habitGroupList.add(hgr) + val record = repository.find(hgr.id!!) + assertThat(record!!.name, equalTo(hgr.name)) + } + + @Test + fun testSize() { + assertThat(habitGroupList.size(), equalTo(10)) + } + + @Test + fun testGetById() { + val hgr1 = habitGroupList.getById(1)!! + assertThat(hgr1.name, equalTo("habit group 1")) + val hgr2 = habitGroupList.getById(2)!! + assertThat(hgr2, equalTo(hgr2)) + } + + @Test + fun testGetById_withInvalid() { + val invalidId = 9183792001L + val hgr1 = habitGroupList.getById(invalidId) + assertNull(hgr1) + } + + @Test + fun testGetByPosition() { + val hgr = habitGroupList.getByPosition(4) + assertThat(hgr.name, equalTo("habit group 5")) + } + + @Test + fun testIndexOf() { + val hgr1 = habitGroupList.getByPosition(5) + assertThat(habitGroupList.indexOf(hgr1), equalTo(5)) + val hgr2 = modelFactory.buildHabitGroup() + assertThat(habitGroupList.indexOf(hgr2), equalTo(-1)) + hgr2.id = 1000L + assertThat(habitGroupList.indexOf(hgr2), equalTo(-1)) + } + + @Test + @Throws(Exception::class) + fun testRemove() { + val hgr = habitGroupList.getById(2) + habitGroupList.remove(hgr!!) + assertThat(habitGroupList.indexOf(hgr), equalTo(-1)) + + var rec = repository.find(2L) + assertNull(rec) + rec = repository.find(3L)!! + assertThat(rec.position, equalTo(1)) + } + + @Test + fun testRemove_orderByName() { + habitGroupList.primaryOrder = HabitList.Order.BY_NAME_DESC + val hgr = habitGroupList.getById(2) + habitGroupList.remove(hgr!!) + assertThat(habitGroupList.indexOf(hgr), equalTo(-1)) + + var rec = repository.find(2L) + assertNull(rec) + rec = repository.find(3L)!! + assertThat(rec.position, equalTo(1)) + } + + @Test + fun testReorder() { + val hgr3 = habitGroupList.getById(3)!! + val hgr4 = habitGroupList.getById(4)!! + habitGroupList.reorder(hgr4, hgr3) + val record3 = repository.find(3L)!! + assertThat(record3.position, equalTo(3)) + val record4 = repository.find(4L)!! + assertThat(record4.position, equalTo(2)) + } +} diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/records/HabitGroupRecordTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/records/HabitGroupRecordTest.kt new file mode 100644 index 000000000..da327ebd1 --- /dev/null +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/records/HabitGroupRecordTest.kt @@ -0,0 +1,65 @@ +/* + * 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.models.sqlite.records + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.isoron.uhabits.core.BaseUnitTest +import org.isoron.uhabits.core.models.PaletteColor +import org.isoron.uhabits.core.models.Reminder +import org.isoron.uhabits.core.models.WeekdayList +import org.junit.Test + +class HabitGroupRecordTest : BaseUnitTest() { + @Test + fun testCopyRestore1() { + val original = modelFactory.buildHabitGroup().apply { + name = "Hello world" + question = "Did you greet the world today?" + color = PaletteColor(1) + isArchived = true + reminder = Reminder(8, 30, WeekdayList.EVERY_DAY) + id = 1000L + position = 20 + } + val record = HabitGroupRecord() + record.copyFrom(original) + val duplicate = modelFactory.buildHabitGroup() + record.copyTo(duplicate) + assertThat(original, equalTo(duplicate)) + } + + @Test + fun testCopyRestore2() { + val original = modelFactory.buildHabitGroup().apply { + name = "Hello world" + question = "Did you greet the world today?" + color = PaletteColor(5) + isArchived = false + reminder = null + id = 1L + position = 15 + } + val record = HabitGroupRecord() + record.copyFrom(original) + val duplicate = modelFactory.buildHabitGroup() + record.copyTo(duplicate) + assertThat(original, equalTo(duplicate)) + } +}