Move test sources from jvmTest to commonTest
This commit is contained in:
parent
b37af7949c
commit
a93e871daf
@ -93,6 +93,17 @@ interface UserFile {
|
|||||||
* parent directory (or this file itself, if it represents a directory).
|
* parent directory (or this file itself, if it represents a directory).
|
||||||
*/
|
*/
|
||||||
fun resolve(child: String): UserFile
|
fun resolve(child: String): UserFile
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of files and directories within this directory, or null
|
||||||
|
* if this path is not a directory or does not exist.
|
||||||
|
*/
|
||||||
|
suspend fun listFiles(): List<UserFile>?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates this directory and any necessary parent directories.
|
||||||
|
*/
|
||||||
|
suspend fun mkdirs()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2025 Álinson Santos Xavier <git@axavier.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.platform.io
|
||||||
|
|
||||||
|
class ZipEntry(val name: String, val content: String)
|
||||||
|
|
||||||
|
expect class ZipReader(bytes: ByteArray) {
|
||||||
|
fun entries(): List<ZipEntry>
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
package org.isoron.platform.io
|
||||||
|
|
||||||
|
expect fun createTestFileOpener(): FileOpener
|
||||||
|
expect fun createTestDatabaseOpener(): DatabaseOpener
|
||||||
@ -18,7 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.core
|
package org.isoron.uhabits.core
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.isoron.platform.io.Database
|
||||||
|
import org.isoron.platform.io.DatabaseOpener
|
||||||
|
import org.isoron.platform.io.FileOpener
|
||||||
import org.isoron.platform.io.TestDatabaseHelper
|
import org.isoron.platform.io.TestDatabaseHelper
|
||||||
|
import org.isoron.platform.io.UserFile
|
||||||
|
import org.isoron.platform.io.createTestDatabaseOpener
|
||||||
|
import org.isoron.platform.io.createTestFileOpener
|
||||||
import org.isoron.platform.time.LocalDate
|
import org.isoron.platform.time.LocalDate
|
||||||
import org.isoron.platform.time.setToday
|
import org.isoron.platform.time.setToday
|
||||||
import org.isoron.uhabits.core.commands.CommandRunner
|
import org.isoron.uhabits.core.commands.CommandRunner
|
||||||
@ -35,6 +42,8 @@ open class BaseUnitTest {
|
|||||||
protected lateinit var modelFactory: ModelFactory
|
protected lateinit var modelFactory: ModelFactory
|
||||||
protected lateinit var taskRunner: SingleThreadTaskRunner
|
protected lateinit var taskRunner: SingleThreadTaskRunner
|
||||||
protected open lateinit var commandRunner: CommandRunner
|
protected open lateinit var commandRunner: CommandRunner
|
||||||
|
protected val fileOpener: FileOpener = createTestFileOpener()
|
||||||
|
protected val databaseOpener: DatabaseOpener = createTestDatabaseOpener()
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
open fun setUp() {
|
open fun setUp() {
|
||||||
@ -47,8 +56,28 @@ open class BaseUnitTest {
|
|||||||
commandRunner = CommandRunner(taskRunner)
|
commandRunner = CommandRunner(taskRunner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun createTempDir(): UserFile = runBlocking {
|
||||||
|
val dir = fileOpener.openUserFile("test-temp-dir-${tempFileCounter++}")
|
||||||
|
dir.mkdirs()
|
||||||
|
dir
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun copyResourceToTempFile(resourcePath: String): UserFile = runBlocking {
|
||||||
|
val cleanPath = resourcePath.removePrefix("/")
|
||||||
|
val tempFile = fileOpener.openUserFile("test-temp-${tempFileCounter++}")
|
||||||
|
fileOpener.openResourceFile(cleanPath).copyTo(tempFile)
|
||||||
|
tempFile
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun openDatabaseResource(resourcePath: String): Database = runBlocking {
|
||||||
|
val tempFile = copyResourceToTempFile(resourcePath)
|
||||||
|
databaseOpener.open(tempFile.pathString)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun buildMemoryDatabase(): org.isoron.platform.io.Database {
|
private var tempFileCounter = 0
|
||||||
|
|
||||||
|
fun buildMemoryDatabase(): Database {
|
||||||
return TestDatabaseHelper.createEmptyDatabase()
|
return TestDatabaseHelper.createEmptyDatabase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,29 +19,24 @@
|
|||||||
package org.isoron.uhabits.core.database.migrations
|
package org.isoron.uhabits.core.database.migrations
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
|
||||||
import org.hamcrest.Matchers
|
|
||||||
import org.hamcrest.Matchers.equalTo
|
|
||||||
import org.isoron.platform.io.Database
|
import org.isoron.platform.io.Database
|
||||||
import org.isoron.platform.io.JavaFileOpener
|
|
||||||
import org.isoron.platform.io.migrateTo
|
import org.isoron.platform.io.migrateTo
|
||||||
import org.isoron.platform.io.querySingle
|
import org.isoron.platform.io.querySingle
|
||||||
import org.isoron.platform.io.run
|
import org.isoron.platform.io.run
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
import org.isoron.uhabits.core.BaseUnitTest
|
||||||
import org.junit.Test
|
import kotlin.test.Test
|
||||||
import org.junit.jupiter.api.Assertions.assertThrows
|
import kotlin.test.assertContains
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
class Version22Test : JvmBaseUnitTest() {
|
class Version22Test : BaseUnitTest() {
|
||||||
private lateinit var db: Database
|
private lateinit var db: Database
|
||||||
|
|
||||||
@Throws(Exception::class)
|
|
||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
db = openDatabaseResource("/databases/021.db")
|
db = openDatabaseResource("/databases/021.db")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val fileOpener = JavaFileOpener()
|
|
||||||
|
|
||||||
private fun migrateTo(version: Int) = runBlocking {
|
private fun migrateTo(version: Int) = runBlocking {
|
||||||
db.migrateTo(version) { v ->
|
db.migrateTo(version) { v ->
|
||||||
val path = "migrations/%02d.sql".format(v)
|
val path = "migrations/%02d.sql".format(v)
|
||||||
@ -52,10 +47,10 @@ class Version22Test : JvmBaseUnitTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun testKeepValidReps() {
|
fun testKeepValidReps() {
|
||||||
val before = db.querySingle("select count(*) from repetitions") { it.getInt(0) }
|
val before = db.querySingle("select count(*) from repetitions") { it.getInt(0) }
|
||||||
assertThat(before, equalTo(3))
|
assertEquals(3, before)
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val after = db.querySingle("select count(*) from repetitions") { it.getInt(0) }
|
val after = db.querySingle("select count(*) from repetitions") { it.getInt(0) }
|
||||||
assertThat(after, equalTo(3))
|
assertEquals(3, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -64,21 +59,21 @@ class Version22Test : JvmBaseUnitTest() {
|
|||||||
val before = db.querySingle(
|
val before = db.querySingle(
|
||||||
"select count(*) from repetitions where habit = 99999"
|
"select count(*) from repetitions where habit = 99999"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(before, equalTo(1))
|
assertEquals(1, before)
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val after = db.querySingle(
|
val after = db.querySingle(
|
||||||
"select count(*) from repetitions where habit = 99999"
|
"select count(*) from repetitions where habit = 99999"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(after, equalTo(0))
|
assertEquals(0, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDisallowNewRepsWithInvalidRef() {
|
fun testDisallowNewRepsWithInvalidRef() {
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val exception = assertThrows(Exception::class.java) {
|
val exception = assertFailsWith<Exception> {
|
||||||
db.run("insert into Repetitions(habit, timestamp, value) values (99999, 100, 2)")
|
db.run("insert into Repetitions(habit, timestamp, value) values (99999, 100, 2)")
|
||||||
}
|
}
|
||||||
assertThat(exception.message, Matchers.containsString("constraint"))
|
assertContains(exception.message!!, "constraint")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -87,21 +82,21 @@ class Version22Test : JvmBaseUnitTest() {
|
|||||||
val before = db.querySingle(
|
val before = db.querySingle(
|
||||||
"select count(*) from repetitions where timestamp is null"
|
"select count(*) from repetitions where timestamp is null"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(before, equalTo(1))
|
assertEquals(1, before)
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val after = db.querySingle(
|
val after = db.querySingle(
|
||||||
"select count(*) from repetitions where timestamp is null"
|
"select count(*) from repetitions where timestamp is null"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(after, equalTo(0))
|
assertEquals(0, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDisallowNullTimestamp() {
|
fun testDisallowNullTimestamp() {
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val exception = assertThrows(Exception::class.java) {
|
val exception = assertFailsWith<Exception> {
|
||||||
db.run("insert into Repetitions(habit, value) values (0, 2)")
|
db.run("insert into Repetitions(habit, value) values (0, 2)")
|
||||||
}
|
}
|
||||||
assertThat(exception.message, Matchers.containsString("constraint"))
|
assertContains(exception.message!!, "constraint")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -110,21 +105,21 @@ class Version22Test : JvmBaseUnitTest() {
|
|||||||
val before = db.querySingle(
|
val before = db.querySingle(
|
||||||
"select count(*) from repetitions where habit is null"
|
"select count(*) from repetitions where habit is null"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(before, equalTo(1))
|
assertEquals(1, before)
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val after = db.querySingle(
|
val after = db.querySingle(
|
||||||
"select count(*) from repetitions where habit is null"
|
"select count(*) from repetitions where habit is null"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(after, equalTo(0))
|
assertEquals(0, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDisallowNullHabit() {
|
fun testDisallowNullHabit() {
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val exception = assertThrows(Exception::class.java) {
|
val exception = assertFailsWith<Exception> {
|
||||||
db.run("insert into Repetitions(timestamp, value) values (5, 2)")
|
db.run("insert into Repetitions(timestamp, value) values (5, 2)")
|
||||||
}
|
}
|
||||||
assertThat(exception.message, Matchers.containsString("constraint"))
|
assertContains(exception.message!!, "constraint")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -135,21 +130,21 @@ class Version22Test : JvmBaseUnitTest() {
|
|||||||
val before = db.querySingle(
|
val before = db.querySingle(
|
||||||
"select count(*) from repetitions where timestamp=100 and habit=0"
|
"select count(*) from repetitions where timestamp=100 and habit=0"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(before, equalTo(3))
|
assertEquals(3, before)
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
val after = db.querySingle(
|
val after = db.querySingle(
|
||||||
"select count(*) from repetitions where timestamp=100 and habit=0"
|
"select count(*) from repetitions where timestamp=100 and habit=0"
|
||||||
) { it.getInt(0) }
|
) { it.getInt(0) }
|
||||||
assertThat(after, equalTo(1))
|
assertEquals(1, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDisallowNewDuplicateTimestamps() {
|
fun testDisallowNewDuplicateTimestamps() {
|
||||||
migrateTo(22)
|
migrateTo(22)
|
||||||
db.run("insert into repetitions(habit, timestamp, value)values (0, 100, 2)")
|
db.run("insert into repetitions(habit, timestamp, value)values (0, 100, 2)")
|
||||||
val exception = assertThrows(Exception::class.java) {
|
val exception = assertFailsWith<Exception> {
|
||||||
db.run("insert into repetitions(habit, timestamp, value)values (0, 100, 5)")
|
db.run("insert into repetitions(habit, timestamp, value)values (0, 100, 5)")
|
||||||
}
|
}
|
||||||
assertThat(exception.message, Matchers.containsString("constraint"))
|
assertContains(exception.message!!, "constraint")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,16 +20,14 @@
|
|||||||
package org.isoron.uhabits.core.database.migrations
|
package org.isoron.uhabits.core.database.migrations
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.hamcrest.CoreMatchers.equalTo
|
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
|
||||||
import org.isoron.platform.io.Database
|
import org.isoron.platform.io.Database
|
||||||
import org.isoron.platform.io.JavaFileOpener
|
|
||||||
import org.isoron.platform.io.migrateTo
|
import org.isoron.platform.io.migrateTo
|
||||||
import org.isoron.platform.io.query
|
import org.isoron.platform.io.query
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
import org.isoron.uhabits.core.BaseUnitTest
|
||||||
import org.junit.Test
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class Version23Test : JvmBaseUnitTest() {
|
class Version23Test : BaseUnitTest() {
|
||||||
|
|
||||||
private lateinit var db: Database
|
private lateinit var db: Database
|
||||||
|
|
||||||
@ -38,8 +36,6 @@ class Version23Test : JvmBaseUnitTest() {
|
|||||||
db = openDatabaseResource("/databases/022.db")
|
db = openDatabaseResource("/databases/022.db")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val fileOpener = JavaFileOpener()
|
|
||||||
|
|
||||||
private fun migrateTo(version: Int) = runBlocking {
|
private fun migrateTo(version: Int) = runBlocking {
|
||||||
db.migrateTo(version) { v ->
|
db.migrateTo(version) { v ->
|
||||||
val path = "migrations/%02d.sql".format(v)
|
val path = "migrations/%02d.sql".format(v)
|
||||||
@ -48,13 +44,13 @@ class Version23Test : JvmBaseUnitTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test migrate to 23 creates question column`() {
|
fun testMigrateTo23CreatesQuestionColumn() {
|
||||||
migrateTo(23)
|
migrateTo(23)
|
||||||
db.query("select question from Habits") {}
|
db.query("select question from Habits") {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test migrate to 23 moves description to question column`() {
|
fun testMigrateTo23MovesDescriptionToQuestionColumn() {
|
||||||
val descriptions = mutableListOf<String?>()
|
val descriptions = mutableListOf<String?>()
|
||||||
db.query("select description from Habits") { stmt ->
|
db.query("select description from Habits") { stmt ->
|
||||||
descriptions.add(stmt.getTextOrNull(0))
|
descriptions.add(stmt.getTextOrNull(0))
|
||||||
@ -68,15 +64,15 @@ class Version23Test : JvmBaseUnitTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i in descriptions.indices) {
|
for (i in descriptions.indices) {
|
||||||
assertThat(questions[i], equalTo(descriptions[i]))
|
assertEquals(descriptions[i], questions[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test migrate to 23 sets description to null`() {
|
fun testMigrateTo23SetsDescriptionToNull() {
|
||||||
migrateTo(23)
|
migrateTo(23)
|
||||||
db.query("select description from Habits") { stmt ->
|
db.query("select description from Habits") { stmt ->
|
||||||
assertThat(stmt.getTextOrNull(0), equalTo(""))
|
assertEquals("", stmt.getTextOrNull(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2025 Álinson Santos Xavier <git@axavier.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.isoron.uhabits.core.io
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.isoron.platform.io.ZipReader
|
||||||
|
import org.isoron.uhabits.core.BaseUnitTest
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class HabitsCSVExporterTest : BaseUnitTest() {
|
||||||
|
|
||||||
|
override fun setUp() {
|
||||||
|
super.setUp()
|
||||||
|
habitList.add(fixtures.createShortHabit())
|
||||||
|
habitList.add(fixtures.createEmptyHabit())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testExportCSV() = runBlocking {
|
||||||
|
val selected: MutableList<Habit> = mutableListOf()
|
||||||
|
for (h in habitList) selected.add(h)
|
||||||
|
val exporter = HabitsCSVExporter(habitList, selected)
|
||||||
|
val bytes = exporter.writeArchive()
|
||||||
|
assertTrue(bytes.isNotEmpty())
|
||||||
|
|
||||||
|
val entries = ZipReader(bytes).entries()
|
||||||
|
|
||||||
|
val filesToCheck = arrayOf(
|
||||||
|
"001 Meditate/Checkmarks.csv",
|
||||||
|
"001 Meditate/Scores.csv",
|
||||||
|
"002 Wake up early/Checkmarks.csv",
|
||||||
|
"002 Wake up early/Scores.csv",
|
||||||
|
"Checkmarks.csv",
|
||||||
|
"Habits.csv",
|
||||||
|
"Scores.csv"
|
||||||
|
)
|
||||||
|
|
||||||
|
for (file in filesToCheck) {
|
||||||
|
val entry = entries.find { it.name == file }
|
||||||
|
assertNotNull(entry, "$file should exist in zip")
|
||||||
|
val expected = fileOpener.openResourceFile("csv_export/$file").lines()
|
||||||
|
assertEquals(expected, entry.content.trimEnd().lines(), "content mismatch for $file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,39 +19,27 @@
|
|||||||
package org.isoron.uhabits.core.io
|
package org.isoron.uhabits.core.io
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
|
||||||
import org.hamcrest.core.IsEqual.equalTo
|
|
||||||
import org.isoron.platform.io.JavaFileOpener
|
|
||||||
import org.isoron.platform.io.JavaUserFile
|
|
||||||
import org.isoron.platform.time.LocalDate
|
import org.isoron.platform.time.LocalDate
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
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
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.HabitType
|
import org.isoron.uhabits.core.models.HabitType
|
||||||
import org.junit.Before
|
import kotlin.test.Test
|
||||||
import org.junit.Test
|
import kotlin.test.assertEquals
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class ImportTest : JvmBaseUnitTest() {
|
class ImportTest : BaseUnitTest() {
|
||||||
@Before
|
|
||||||
@Throws(Exception::class)
|
|
||||||
override fun setUp() {
|
|
||||||
super.setUp()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testHabitBullCSV() {
|
fun testHabitBullCSV() {
|
||||||
importFromFile("habitbull.csv")
|
importFromFile("habitbull.csv")
|
||||||
assertThat(habitList.size(), equalTo(4))
|
assertEquals(4, habitList.size())
|
||||||
val habit = habitList.getByPosition(0)
|
val habit = habitList.getByPosition(0)
|
||||||
assertThat(habit.name, equalTo("Breed dragons"))
|
assertEquals("Breed dragons", habit.name)
|
||||||
assertThat(habit.description, equalTo("with love and fire"))
|
assertEquals("with love and fire", habit.description)
|
||||||
assertThat(habit.frequency, equalTo(Frequency.DAILY))
|
assertEquals(Frequency.DAILY, habit.frequency)
|
||||||
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))
|
||||||
@ -59,14 +47,13 @@ class ImportTest : JvmBaseUnitTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testHabitBullCSV2() {
|
fun testHabitBullCSV2() {
|
||||||
importFromFile("habitbull2.csv")
|
importFromFile("habitbull2.csv")
|
||||||
assertThat(habitList.size(), equalTo(6))
|
assertEquals(6, habitList.size())
|
||||||
val habit = habitList.getByPosition(2)
|
val habit = habitList.getByPosition(2)
|
||||||
assertThat(habit.name, equalTo("H3"))
|
assertEquals("H3", habit.name)
|
||||||
assertThat(habit.description, equalTo("Habit 3"))
|
assertEquals("Habit 3", habit.description)
|
||||||
assertThat(habit.frequency, equalTo(Frequency.DAILY))
|
assertEquals(Frequency.DAILY, habit.frequency)
|
||||||
assertTrue(isChecked(habit, 2019, 4, 11))
|
assertTrue(isChecked(habit, 2019, 4, 11))
|
||||||
assertTrue(isChecked(habit, 2019, 5, 7))
|
assertTrue(isChecked(habit, 2019, 5, 7))
|
||||||
assertFalse(isChecked(habit, 2019, 6, 14))
|
assertFalse(isChecked(habit, 2019, 6, 14))
|
||||||
@ -75,88 +62,83 @@ class ImportTest : JvmBaseUnitTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testHabitBullCSV3() {
|
fun testHabitBullCSV3() {
|
||||||
importFromFile("habitbull3.csv")
|
importFromFile("habitbull3.csv")
|
||||||
assertThat(habitList.size(), equalTo(2))
|
assertEquals(2, habitList.size())
|
||||||
|
|
||||||
val habit = habitList.getByPosition(0)
|
val habit = habitList.getByPosition(0)
|
||||||
assertThat(habit.name, equalTo("Pushups"))
|
assertEquals("Pushups", habit.name)
|
||||||
assertThat(habit.type, equalTo(HabitType.NUMERICAL))
|
assertEquals(HabitType.NUMERICAL, habit.type)
|
||||||
assertThat(habit.description, equalTo(""))
|
assertEquals("", habit.description)
|
||||||
assertThat(habit.frequency, equalTo(Frequency.DAILY))
|
assertEquals(Frequency.DAILY, habit.frequency)
|
||||||
assertThat(getValue(habit, 2021, 9, 1), equalTo(30000))
|
assertEquals(30000, getValue(habit, 2021, 9, 1))
|
||||||
assertThat(getValue(habit, 2022, 1, 8), equalTo(100000))
|
assertEquals(100000, getValue(habit, 2022, 1, 8))
|
||||||
|
|
||||||
val habit2 = habitList.getByPosition(1)
|
val habit2 = habitList.getByPosition(1)
|
||||||
assertThat(habit2.name, equalTo("run"))
|
assertEquals("run", habit2.name)
|
||||||
assertThat(habit2.type, equalTo(HabitType.YES_NO))
|
assertEquals(HabitType.YES_NO, habit2.type)
|
||||||
assertThat(habit2.description, equalTo(""))
|
assertEquals("", habit2.description)
|
||||||
assertThat(habit2.frequency, equalTo(Frequency.DAILY))
|
assertEquals(Frequency.DAILY, habit2.frequency)
|
||||||
assertTrue(isChecked(habit2, 2022, 1, 3))
|
assertTrue(isChecked(habit2, 2022, 1, 3))
|
||||||
assertTrue(isChecked(habit2, 2022, 1, 18))
|
assertTrue(isChecked(habit2, 2022, 1, 18))
|
||||||
assertTrue(isChecked(habit2, 2022, 1, 19))
|
assertTrue(isChecked(habit2, 2022, 1, 19))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testHabitBullCSV4() {
|
fun testHabitBullCSV4() {
|
||||||
importFromFile("habitbull4.csv")
|
importFromFile("habitbull4.csv")
|
||||||
assertThat(habitList.size(), equalTo(1))
|
assertEquals(1, habitList.size())
|
||||||
|
|
||||||
val habit = habitList.getByPosition(0)
|
val habit = habitList.getByPosition(0)
|
||||||
assertThat(habit.name, equalTo("Caffeine"))
|
assertEquals("Caffeine", habit.name)
|
||||||
assertThat(habit.type, equalTo(HabitType.NUMERICAL))
|
assertEquals(HabitType.NUMERICAL, habit.type)
|
||||||
assertThat(habit.description, equalTo(""))
|
assertEquals("", habit.description)
|
||||||
assertThat(habit.frequency, equalTo(Frequency.DAILY))
|
assertEquals(Frequency.DAILY, habit.frequency)
|
||||||
assertThat(getValue(habit, 2022, 11, 21), equalTo(80000))
|
assertEquals(80000, getValue(habit, 2022, 11, 21))
|
||||||
assertThat(getValue(habit, 2022, 11, 22), equalTo(80000))
|
assertEquals(80000, getValue(habit, 2022, 11, 22))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testLoopDB() {
|
fun testLoopDB() {
|
||||||
importFromFile("loop.db")
|
importFromFile("loop.db")
|
||||||
assertThat(habitList.size(), equalTo(9))
|
assertEquals(9, habitList.size())
|
||||||
val habit = habitList.getByPosition(0)
|
val habit = habitList.getByPosition(0)
|
||||||
assertThat(habit.name, equalTo("Wake up early"))
|
assertEquals("Wake up early", habit.name)
|
||||||
assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK))
|
assertEquals(Frequency.THREE_TIMES_PER_WEEK, habit.frequency)
|
||||||
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))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testRewireDB() {
|
fun testRewireDB() {
|
||||||
importFromFile("rewire.db")
|
importFromFile("rewire.db")
|
||||||
assertThat(habitList.size(), equalTo(3))
|
assertEquals(3, habitList.size())
|
||||||
var habit = habitList.getByPosition(1)
|
var habit = habitList.getByPosition(1)
|
||||||
assertThat(habit.name, equalTo("Wake up early"))
|
assertEquals("Wake up early", habit.name)
|
||||||
assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK))
|
assertEquals(Frequency.THREE_TIMES_PER_WEEK, habit.frequency)
|
||||||
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, equalTo("brush teeth"))
|
assertEquals("brush teeth", habit.name)
|
||||||
assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK))
|
assertEquals(Frequency.THREE_TIMES_PER_WEEK, habit.frequency)
|
||||||
assertThat(habit.hasReminder(), equalTo(true))
|
assertEquals(true, habit.hasReminder())
|
||||||
val reminder = habit.reminder
|
val reminder = habit.reminder
|
||||||
assertThat(reminder!!.hour, equalTo(8))
|
assertEquals(8, reminder!!.hour)
|
||||||
assertThat(reminder.minute, equalTo(0))
|
assertEquals(0, reminder.minute)
|
||||||
val reminderDays = booleanArrayOf(false, true, true, true, true, true, false)
|
val reminderDays = booleanArrayOf(false, true, true, true, true, true, false)
|
||||||
assertThat(reminder.days.toArray(), equalTo(reminderDays))
|
assertEquals(reminderDays.toList(), reminder.days.toArray().toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testTickmateDB() {
|
fun testTickmateDB() {
|
||||||
importFromFile("tickmate.db")
|
importFromFile("tickmate.db")
|
||||||
assertThat(habitList.size(), equalTo(3))
|
assertEquals(3, habitList.size())
|
||||||
val h = habitList.getByPosition(2)
|
val h = habitList.getByPosition(2)
|
||||||
assertThat(h.name, equalTo("Vegan"))
|
assertEquals("Vegan", h.name)
|
||||||
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))
|
||||||
@ -175,13 +157,9 @@ class ImportTest : JvmBaseUnitTest() {
|
|||||||
return h.originalEntries.get(LocalDate(year, month, day)).notes == notes
|
return h.originalEntries.get(LocalDate(year, month, day)).notes == notes
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
|
||||||
private fun importFromFile(assetFilename: String) = runBlocking {
|
private fun importFromFile(assetFilename: String) = runBlocking {
|
||||||
val file = File.createTempFile("asset", "")
|
val userFile = copyResourceToTempFile(assetFilename)
|
||||||
copyAssetToFile(assetFilename, file)
|
assertTrue(userFile.exists())
|
||||||
assertTrue(file.exists())
|
|
||||||
assertTrue(file.canRead())
|
|
||||||
val userFile = JavaUserFile(file.toPath())
|
|
||||||
val importer = GenericImporter(
|
val importer = GenericImporter(
|
||||||
LoopDBImporter(
|
LoopDBImporter(
|
||||||
habitList,
|
habitList,
|
||||||
@ -189,7 +167,7 @@ class ImportTest : JvmBaseUnitTest() {
|
|||||||
databaseOpener,
|
databaseOpener,
|
||||||
commandRunner,
|
commandRunner,
|
||||||
StandardLogging(),
|
StandardLogging(),
|
||||||
JavaFileOpener()
|
fileOpener
|
||||||
),
|
),
|
||||||
RewireDBImporter(habitList, modelFactory, databaseOpener),
|
RewireDBImporter(habitList, modelFactory, databaseOpener),
|
||||||
TickmateDBImporter(habitList, modelFactory, databaseOpener),
|
TickmateDBImporter(habitList, modelFactory, databaseOpener),
|
||||||
@ -197,6 +175,6 @@ class ImportTest : JvmBaseUnitTest() {
|
|||||||
)
|
)
|
||||||
assertTrue(importer.canHandle(userFile))
|
assertTrue(importer.canHandle(userFile))
|
||||||
importer.importHabitsFromFile(userFile)
|
importer.importHabitsFromFile(userFile)
|
||||||
file.delete()
|
userFile.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,9 +20,7 @@ package org.isoron.uhabits.core.models.sqlite
|
|||||||
|
|
||||||
import dev.mokkery.mock
|
import dev.mokkery.mock
|
||||||
import dev.mokkery.verify
|
import dev.mokkery.verify
|
||||||
import org.hamcrest.CoreMatchers.equalTo
|
import org.isoron.uhabits.core.BaseUnitTest
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
|
||||||
import org.isoron.uhabits.core.database.HabitRepository
|
import org.isoron.uhabits.core.database.HabitRepository
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.HabitList
|
import org.isoron.uhabits.core.models.HabitList
|
||||||
@ -31,20 +29,19 @@ import org.isoron.uhabits.core.models.ModelObservable
|
|||||||
import org.isoron.uhabits.core.models.Reminder
|
import org.isoron.uhabits.core.models.Reminder
|
||||||
import org.isoron.uhabits.core.models.WeekdayList
|
import org.isoron.uhabits.core.models.WeekdayList
|
||||||
import org.isoron.uhabits.core.test.HabitFixtures
|
import org.isoron.uhabits.core.test.HabitFixtures
|
||||||
import org.junit.After
|
import kotlin.test.AfterTest
|
||||||
import org.junit.Assert.assertThrows
|
import kotlin.test.Test
|
||||||
import org.junit.Test
|
import kotlin.test.assertEquals
|
||||||
import java.util.ArrayList
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
class SQLiteHabitListTest : JvmBaseUnitTest() {
|
class SQLiteHabitListTest : BaseUnitTest() {
|
||||||
private lateinit var repository: HabitRepository
|
private lateinit var repository: HabitRepository
|
||||||
private var listener: ModelObservable.Listener = mock()
|
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)
|
|
||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
val db = buildMemoryDatabase()
|
val db = buildMemoryDatabase()
|
||||||
@ -75,7 +72,7 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
|||||||
habitList.observable.addListener(listener)
|
habitList.observable.addListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@AfterTest
|
||||||
fun tearDown() {
|
fun tearDown() {
|
||||||
habitList.observable.removeListener(listener)
|
habitList.observable.removeListener(listener)
|
||||||
}
|
}
|
||||||
@ -85,7 +82,7 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
|||||||
val habit = modelFactory.buildHabit()
|
val habit = modelFactory.buildHabit()
|
||||||
habitList.add(habit)
|
habitList.add(habit)
|
||||||
verify { listener.onModelChange() }
|
verify { listener.onModelChange() }
|
||||||
assertThrows(IllegalArgumentException::class.java) {
|
assertFailsWith<IllegalArgumentException> {
|
||||||
habitList.add(habit)
|
habitList.add(habit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,10 +93,10 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
|||||||
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, equalTo(12300L))
|
assertEquals(12300L, habit.id)
|
||||||
val all = repository.findAll()
|
val all = repository.findAll()
|
||||||
val record = all.find { it.id == 12300L }
|
val record = all.find { it.id == 12300L }
|
||||||
assertThat(record!!.name, equalTo(habit.name))
|
assertEquals(habit.name, record!!.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -110,20 +107,20 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
|||||||
habitList.add(habit)
|
habitList.add(habit)
|
||||||
val all = repository.findAll()
|
val all = repository.findAll()
|
||||||
val record = all.find { it.id == habit.id }
|
val record = all.find { it.id == habit.id }
|
||||||
assertThat(record!!.name, equalTo(habit.name))
|
assertEquals(habit.name, record!!.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSize() {
|
fun testSize() {
|
||||||
assertThat(habitList.size(), equalTo(10))
|
assertEquals(10, habitList.size())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testGetById() {
|
fun testGetById() {
|
||||||
val h1 = habitList.getById(1)!!
|
val h1 = habitList.getById(1)!!
|
||||||
assertThat(h1.name, equalTo("habit 1"))
|
assertEquals("habit 1", h1.name)
|
||||||
val h2 = habitList.getById(2)!!
|
val h2 = habitList.getById(2)!!
|
||||||
assertThat(h2, equalTo(h2))
|
assertEquals(h2, h2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -136,31 +133,30 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun testGetByPosition() {
|
fun testGetByPosition() {
|
||||||
val h = habitList.getByPosition(4)
|
val h = habitList.getByPosition(4)
|
||||||
assertThat(h.name, equalTo("habit 5"))
|
assertEquals("habit 5", h.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIndexOf() {
|
fun testIndexOf() {
|
||||||
val h1 = habitList.getByPosition(5)
|
val h1 = habitList.getByPosition(5)
|
||||||
assertThat(habitList.indexOf(h1), equalTo(5))
|
assertEquals(5, habitList.indexOf(h1))
|
||||||
val h2 = modelFactory.buildHabit()
|
val h2 = modelFactory.buildHabit()
|
||||||
assertThat(habitList.indexOf(h2), equalTo(-1))
|
assertEquals(-1, habitList.indexOf(h2))
|
||||||
h2.id = 1000L
|
h2.id = 1000L
|
||||||
assertThat(habitList.indexOf(h2), equalTo(-1))
|
assertEquals(-1, habitList.indexOf(h2))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(Exception::class)
|
|
||||||
fun testRemove() {
|
fun testRemove() {
|
||||||
val h = habitList.getById(2)
|
val h = habitList.getById(2)
|
||||||
habitList.remove(h!!)
|
habitList.remove(h!!)
|
||||||
assertThat(habitList.indexOf(h), equalTo(-1))
|
assertEquals(-1, habitList.indexOf(h))
|
||||||
|
|
||||||
val all = repository.findAll()
|
val all = repository.findAll()
|
||||||
val rec2 = all.find { it.id == 2L }
|
val rec2 = all.find { it.id == 2L }
|
||||||
assertNull(rec2)
|
assertNull(rec2)
|
||||||
val rec3 = all.find { it.id == 3L }!!
|
val rec3 = all.find { it.id == 3L }!!
|
||||||
assertThat(rec3.position, equalTo(1))
|
assertEquals(1, rec3.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -168,13 +164,13 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
|||||||
habitList.primaryOrder = HabitList.Order.BY_NAME_DESC
|
habitList.primaryOrder = HabitList.Order.BY_NAME_DESC
|
||||||
val h = habitList.getById(2)
|
val h = habitList.getById(2)
|
||||||
habitList.remove(h!!)
|
habitList.remove(h!!)
|
||||||
assertThat(habitList.indexOf(h), equalTo(-1))
|
assertEquals(-1, habitList.indexOf(h))
|
||||||
|
|
||||||
val all = repository.findAll()
|
val all = repository.findAll()
|
||||||
val rec2 = all.find { it.id == 2L }
|
val rec2 = all.find { it.id == 2L }
|
||||||
assertNull(rec2)
|
assertNull(rec2)
|
||||||
val rec3 = all.find { it.id == 3L }!!
|
val rec3 = all.find { it.id == 3L }!!
|
||||||
assertThat(rec3.position, equalTo(1))
|
assertEquals(1, rec3.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -184,8 +180,8 @@ class SQLiteHabitListTest : JvmBaseUnitTest() {
|
|||||||
habitList.reorder(habit4, habit3)
|
habitList.reorder(habit4, habit3)
|
||||||
val all = repository.findAll()
|
val all = repository.findAll()
|
||||||
val record3 = all.find { it.id == 3L }!!
|
val record3 = all.find { it.id == 3L }!!
|
||||||
assertThat(record3.position, equalTo(3))
|
assertEquals(3, record3.position)
|
||||||
val record4 = all.find { it.id == 4L }!!
|
val record4 = all.find { it.id == 4L }!!
|
||||||
assertThat(record4.position, equalTo(2))
|
assertEquals(2, record4.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,24 +25,22 @@ import dev.mokkery.every
|
|||||||
import dev.mokkery.matcher.any
|
import dev.mokkery.matcher.any
|
||||||
import dev.mokkery.mock
|
import dev.mokkery.mock
|
||||||
import dev.mokkery.resetCalls
|
import dev.mokkery.resetCalls
|
||||||
|
import dev.mokkery.spy
|
||||||
import dev.mokkery.verify
|
import dev.mokkery.verify
|
||||||
import org.apache.commons.io.FileUtils
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.isoron.platform.io.UserFile
|
||||||
import org.hamcrest.core.IsEqual.equalTo
|
|
||||||
import org.isoron.platform.io.JavaUserFile
|
|
||||||
import org.isoron.platform.time.getToday
|
import org.isoron.platform.time.getToday
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
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
|
||||||
import org.isoron.uhabits.core.preferences.Preferences
|
import org.isoron.uhabits.core.preferences.Preferences
|
||||||
import org.isoron.uhabits.core.ui.callbacks.NumberPickerCallback
|
import org.isoron.uhabits.core.ui.callbacks.NumberPickerCallback
|
||||||
import org.junit.Before
|
import kotlin.test.Test
|
||||||
import org.junit.Test
|
import kotlin.test.assertEquals
|
||||||
import java.nio.file.Files
|
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
class ListHabitsBehaviorTest : BaseUnitTest() {
|
||||||
private val dirFinder: ListHabitsBehavior.DirFinder = mock()
|
private val dirFinder: ListHabitsBehavior.DirFinder = mock()
|
||||||
|
|
||||||
private val prefs: Preferences = mock()
|
private val prefs: Preferences = mock()
|
||||||
@ -56,15 +54,13 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
|||||||
|
|
||||||
private val bugReporter: ListHabitsBehavior.BugReporter = mock()
|
private val bugReporter: ListHabitsBehavior.BugReporter = mock()
|
||||||
|
|
||||||
@Before
|
|
||||||
@Throws(Exception::class)
|
|
||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
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)
|
||||||
resetCalls(habitList)
|
habitList = spy(habitList)
|
||||||
behavior = ListHabitsBehavior(
|
behavior = ListHabitsBehavior(
|
||||||
habitList,
|
habitList,
|
||||||
dirFinder,
|
dirFinder,
|
||||||
@ -90,29 +86,26 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() {
|
|||||||
screen.showNumberPopup(0.1, "", any())
|
screen.showNumberPopup(0.1, "", any())
|
||||||
}
|
}
|
||||||
capturedPicker!!.onNumberPicked(100.0, "")
|
capturedPicker!!.onNumberPicked(100.0, "")
|
||||||
assertThat(habit2.computedEntries.get(today).value, equalTo(100000))
|
assertEquals(100000, habit2.computedEntries.get(today).value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(Exception::class)
|
|
||||||
fun testOnExportCSV() {
|
fun testOnExportCSV() {
|
||||||
val outputDir = Files.createTempDirectory("CSV").toFile()
|
val outputDir = createTempDir()
|
||||||
every { dirFinder.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath())
|
every { dirFinder.getCSVOutputDir() } returns outputDir
|
||||||
behavior.onExportCSV()
|
behavior.onExportCSV()
|
||||||
verify { screen.showSendFileScreen(any()) }
|
verify { screen.showSendFileScreen(any()) }
|
||||||
assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1))
|
val files = runBlocking { outputDir.listFiles() }
|
||||||
FileUtils.deleteDirectory(outputDir)
|
assertEquals(1, files!!.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(Exception::class)
|
|
||||||
fun testOnExportCSV_fail() {
|
fun testOnExportCSV_fail() {
|
||||||
val outputDir = Files.createTempDirectory("CSV").toFile()
|
val mockDir: UserFile = mock()
|
||||||
outputDir.setWritable(false)
|
every { mockDir.resolve(any()) } throws RuntimeException("not writable")
|
||||||
every { dirFinder.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath())
|
every { dirFinder.getCSVOutputDir() } returns mockDir
|
||||||
behavior.onExportCSV()
|
behavior.onExportCSV()
|
||||||
verify { screen.showMessage(ListHabitsBehavior.Message.COULD_NOT_EXPORT) }
|
verify { screen.showMessage(ListHabitsBehavior.Message.COULD_NOT_EXPORT) }
|
||||||
assertTrue(outputDir.delete())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -22,22 +22,18 @@ import dev.mokkery.answering.returns
|
|||||||
import dev.mokkery.every
|
import dev.mokkery.every
|
||||||
import dev.mokkery.mock
|
import dev.mokkery.mock
|
||||||
import dev.mokkery.verify
|
import dev.mokkery.verify
|
||||||
import org.apache.commons.io.FileUtils
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.hamcrest.CoreMatchers.equalTo
|
import org.isoron.uhabits.core.BaseUnitTest
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
|
||||||
import org.isoron.platform.io.JavaUserFile
|
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.junit.Test
|
import kotlin.test.Test
|
||||||
import java.nio.file.Files
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class ShowHabitMenuPresenterTest : JvmBaseUnitTest() {
|
class ShowHabitMenuPresenterTest : BaseUnitTest() {
|
||||||
private lateinit var system: ShowHabitMenuPresenter.System
|
private lateinit var system: ShowHabitMenuPresenter.System
|
||||||
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)
|
|
||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
system = mock()
|
system = mock()
|
||||||
@ -60,12 +56,11 @@ class ShowHabitMenuPresenterTest : JvmBaseUnitTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Throws(Exception::class)
|
|
||||||
fun testOnExport() {
|
fun testOnExport() {
|
||||||
val outputDir = Files.createTempDirectory("CSV").toFile()
|
val outputDir = createTempDir()
|
||||||
every { system.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath())
|
every { system.getCSVOutputDir() } returns outputDir
|
||||||
menu.onExportCSV()
|
menu.onExportCSV()
|
||||||
assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1))
|
val files = runBlocking { outputDir.listFiles() }
|
||||||
FileUtils.deleteDirectory(outputDir)
|
assertEquals(1, files!!.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package org.isoron.uhabits.core.utils
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.isoron.uhabits.core.BaseUnitTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class FileExtensionsTest : BaseUnitTest() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testIsSQLite3File() = runBlocking {
|
||||||
|
val userFile = copyResourceToTempFile("loop.db")
|
||||||
|
val isSqlite3File = isSQLite3File(userFile)
|
||||||
|
assertTrue(isSqlite3File)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -103,6 +103,15 @@ class JavaUserFile(val path: Path) : UserFile {
|
|||||||
override fun resolve(child: String): UserFile {
|
override fun resolve(child: String): UserFile {
|
||||||
return JavaUserFile(path.resolve(child))
|
return JavaUserFile(path.resolve(child))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun listFiles(): List<UserFile>? {
|
||||||
|
val files = path.toFile().listFiles() ?: return null
|
||||||
|
return files.map { JavaUserFile(it.toPath()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun mkdirs() {
|
||||||
|
path.toFile().mkdirs()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NewApi")
|
@Suppress("NewApi")
|
||||||
|
|||||||
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2025 Álinson Santos Xavier <git@axavier.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.isoron.platform.io
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.util.zip.ZipInputStream
|
||||||
|
|
||||||
|
actual class ZipReader actual constructor(bytes: ByteArray) {
|
||||||
|
private val data = bytes
|
||||||
|
|
||||||
|
actual fun entries(): List<ZipEntry> {
|
||||||
|
val result = mutableListOf<ZipEntry>()
|
||||||
|
val zis = ZipInputStream(ByteArrayInputStream(data))
|
||||||
|
var entry = zis.nextEntry
|
||||||
|
while (entry != null) {
|
||||||
|
result.add(ZipEntry(entry.name, zis.readBytes().decodeToString()))
|
||||||
|
zis.closeEntry()
|
||||||
|
entry = zis.nextEntry
|
||||||
|
}
|
||||||
|
zis.close()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,7 +20,6 @@
|
|||||||
package org.isoron.platform.io
|
package org.isoron.platform.io
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.util.zip.ZipEntry
|
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
actual class ZipWriter {
|
actual class ZipWriter {
|
||||||
@ -28,7 +27,7 @@ actual class ZipWriter {
|
|||||||
private val zos = ZipOutputStream(baos)
|
private val zos = ZipOutputStream(baos)
|
||||||
|
|
||||||
actual fun addEntry(name: String, content: String) {
|
actual fun addEntry(name: String, content: String) {
|
||||||
zos.putNextEntry(ZipEntry(name))
|
zos.putNextEntry(java.util.zip.ZipEntry(name))
|
||||||
zos.write(content.toByteArray())
|
zos.write(content.toByteArray())
|
||||||
zos.closeEntry()
|
zos.closeEntry()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
package org.isoron.platform.io
|
||||||
|
|
||||||
|
actual fun createTestFileOpener(): FileOpener = JavaFileOpener()
|
||||||
|
actual fun createTestDatabaseOpener(): DatabaseOpener = JavaDatabaseOpener()
|
||||||
@ -20,7 +20,6 @@ package org.isoron.uhabits.core
|
|||||||
|
|
||||||
import dev.mokkery.spy
|
import dev.mokkery.spy
|
||||||
import org.apache.commons.io.IOUtils
|
import org.apache.commons.io.IOUtils
|
||||||
import org.isoron.platform.io.JavaDatabaseOpener
|
|
||||||
import org.isoron.uhabits.core.models.memory.MemoryModelFactory
|
import org.isoron.uhabits.core.models.memory.MemoryModelFactory
|
||||||
import org.isoron.uhabits.core.test.HabitFixtures
|
import org.isoron.uhabits.core.test.HabitFixtures
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -35,8 +34,6 @@ import java.util.GregorianCalendar
|
|||||||
import java.util.TimeZone
|
import java.util.TimeZone
|
||||||
|
|
||||||
open class JvmBaseUnitTest : BaseUnitTest() {
|
open class JvmBaseUnitTest : BaseUnitTest() {
|
||||||
protected var databaseOpener: org.isoron.platform.io.DatabaseOpener = JavaDatabaseOpener()
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
@ -75,13 +72,4 @@ open class JvmBaseUnitTest : BaseUnitTest() {
|
|||||||
if (inputStream != null) return inputStream
|
if (inputStream != null) return inputStream
|
||||||
throw IllegalStateException("asset not found: $fullPath")
|
throw IllegalStateException("asset not found: $fullPath")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
|
||||||
protected fun openDatabaseResource(path: String): org.isoron.platform.io.Database {
|
|
||||||
val original = openAsset(path)
|
|
||||||
val tmpDbFile = File.createTempFile("database", ".db")
|
|
||||||
tmpDbFile.deleteOnExit()
|
|
||||||
IOUtils.copy(original, FileOutputStream(tmpDbFile))
|
|
||||||
return databaseOpener.open(tmpDbFile.absolutePath)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016-2025 Álinson Santos Xavier <git@axavier.org>
|
|
||||||
*
|
|
||||||
* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.isoron.uhabits.core.io
|
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
|
||||||
import org.isoron.uhabits.core.models.Habit
|
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Test
|
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.util.*
|
|
||||||
import java.util.zip.ZipInputStream
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class HabitsCSVExporterTest : JvmBaseUnitTest() {
|
|
||||||
private lateinit var baseDir: File
|
|
||||||
|
|
||||||
@Before
|
|
||||||
@Throws(Exception::class)
|
|
||||||
override fun setUp() {
|
|
||||||
super.setUp()
|
|
||||||
habitList.add(fixtures.createShortHabit())
|
|
||||||
habitList.add(fixtures.createEmptyHabit())
|
|
||||||
baseDir = Files.createTempDirectory("csv").toFile()
|
|
||||||
baseDir.deleteOnExit()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Throws(IOException::class)
|
|
||||||
fun testExportCSV() = runBlocking {
|
|
||||||
val selected: MutableList<Habit> = LinkedList()
|
|
||||||
for (h in habitList) selected.add(h)
|
|
||||||
val exporter = HabitsCSVExporter(habitList, selected)
|
|
||||||
val bytes = exporter.writeArchive()
|
|
||||||
assertTrue(bytes.isNotEmpty())
|
|
||||||
|
|
||||||
// Extract zip entries to baseDir for comparison
|
|
||||||
unzip(bytes)
|
|
||||||
|
|
||||||
val filesToCheck = arrayOf(
|
|
||||||
"001 Meditate/Checkmarks.csv",
|
|
||||||
"001 Meditate/Scores.csv",
|
|
||||||
"002 Wake up early/Checkmarks.csv",
|
|
||||||
"002 Wake up early/Scores.csv",
|
|
||||||
"Checkmarks.csv",
|
|
||||||
"Habits.csv",
|
|
||||||
"Scores.csv"
|
|
||||||
)
|
|
||||||
|
|
||||||
for (file in filesToCheck) {
|
|
||||||
assertPathExists(file)
|
|
||||||
assertFileAndReferenceAreEqual(file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun unzip(bytes: ByteArray) {
|
|
||||||
val zis = ZipInputStream(ByteArrayInputStream(bytes))
|
|
||||||
var entry = zis.nextEntry
|
|
||||||
while (entry != null) {
|
|
||||||
val outFile = File(baseDir, entry.name)
|
|
||||||
outFile.parentFile?.mkdirs()
|
|
||||||
outFile.writeBytes(zis.readBytes())
|
|
||||||
zis.closeEntry()
|
|
||||||
entry = zis.nextEntry
|
|
||||||
}
|
|
||||||
zis.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assertPathExists(s: String) {
|
|
||||||
val file = File(baseDir, s)
|
|
||||||
assertTrue(
|
|
||||||
String.format("File %s should exist", file.absolutePath)
|
|
||||||
) { file.exists() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assertFileAndReferenceAreEqual(s: String) {
|
|
||||||
val assetFilename = String.format("csv_export/%s", s)
|
|
||||||
val actualFile = File(baseDir, s)
|
|
||||||
val expectedFile = File.createTempFile("asset", "")
|
|
||||||
expectedFile.deleteOnExit()
|
|
||||||
copyAssetToFile(assetFilename, expectedFile)
|
|
||||||
val actualContents = actualFile.readText()
|
|
||||||
val expectedContents = expectedFile.readText()
|
|
||||||
assertEquals(expectedContents, actualContents, "content mismatch for $s")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package org.isoron.uhabits.core.utils
|
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.isoron.platform.io.JavaUserFile
|
|
||||||
import org.isoron.uhabits.core.JvmBaseUnitTest
|
|
||||||
import org.junit.Test
|
|
||||||
import java.io.File
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class FileExtensionsTest : JvmBaseUnitTest() {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testIsSQLite3File() = runBlocking {
|
|
||||||
val file = File.createTempFile("asset", "")
|
|
||||||
copyAssetToFile("loop.db", file)
|
|
||||||
val userFile = JavaUserFile(file.toPath())
|
|
||||||
val isSqlite3File = isSQLite3File(userFile)
|
|
||||||
assertTrue(isSqlite3File)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user