diff --git a/uhabits-core/src/commonMain/kotlin/org/isoron/platform/io/Files.kt b/uhabits-core/src/commonMain/kotlin/org/isoron/platform/io/Files.kt index 018ae484..d2a043aa 100644 --- a/uhabits-core/src/commonMain/kotlin/org/isoron/platform/io/Files.kt +++ b/uhabits-core/src/commonMain/kotlin/org/isoron/platform/io/Files.kt @@ -93,6 +93,17 @@ interface UserFile { * parent directory (or this file itself, if it represents a directory). */ 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? + + /** + * Creates this directory and any necessary parent directories. + */ + suspend fun mkdirs() } /** diff --git a/uhabits-core/src/commonMain/kotlin/org/isoron/platform/io/ZipReader.kt b/uhabits-core/src/commonMain/kotlin/org/isoron/platform/io/ZipReader.kt new file mode 100644 index 00000000..68eac000 --- /dev/null +++ b/uhabits-core/src/commonMain/kotlin/org/isoron/platform/io/ZipReader.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016-2025 Á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.platform.io + +class ZipEntry(val name: String, val content: String) + +expect class ZipReader(bytes: ByteArray) { + fun entries(): List +} diff --git a/uhabits-core/src/commonTest/kotlin/org/isoron/platform/io/TestPlatformHelper.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/platform/io/TestPlatformHelper.kt new file mode 100644 index 00000000..fd23154f --- /dev/null +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/platform/io/TestPlatformHelper.kt @@ -0,0 +1,4 @@ +package org.isoron.platform.io + +expect fun createTestFileOpener(): FileOpener +expect fun createTestDatabaseOpener(): DatabaseOpener diff --git a/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/BaseUnitTest.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/BaseUnitTest.kt index b3ff475c..cd132eb0 100644 --- a/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/BaseUnitTest.kt +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/BaseUnitTest.kt @@ -18,7 +18,14 @@ */ 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.UserFile +import org.isoron.platform.io.createTestDatabaseOpener +import org.isoron.platform.io.createTestFileOpener import org.isoron.platform.time.LocalDate import org.isoron.platform.time.setToday import org.isoron.uhabits.core.commands.CommandRunner @@ -35,6 +42,8 @@ open class BaseUnitTest { protected lateinit var modelFactory: ModelFactory protected lateinit var taskRunner: SingleThreadTaskRunner protected open lateinit var commandRunner: CommandRunner + protected val fileOpener: FileOpener = createTestFileOpener() + protected val databaseOpener: DatabaseOpener = createTestDatabaseOpener() @BeforeTest open fun setUp() { @@ -47,8 +56,28 @@ open class BaseUnitTest { 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 { - fun buildMemoryDatabase(): org.isoron.platform.io.Database { + private var tempFileCounter = 0 + + fun buildMemoryDatabase(): Database { return TestDatabaseHelper.createEmptyDatabase() } } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/migrations/Version22Test.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/database/migrations/Version22Test.kt similarity index 76% rename from uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/migrations/Version22Test.kt rename to uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/database/migrations/Version22Test.kt index 24e5c93d..45ceb759 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/migrations/Version22Test.kt +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/database/migrations/Version22Test.kt @@ -19,29 +19,24 @@ package org.isoron.uhabits.core.database.migrations 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.JavaFileOpener import org.isoron.platform.io.migrateTo import org.isoron.platform.io.querySingle import org.isoron.platform.io.run -import org.isoron.uhabits.core.JvmBaseUnitTest -import org.junit.Test -import org.junit.jupiter.api.Assertions.assertThrows +import org.isoron.uhabits.core.BaseUnitTest +import kotlin.test.Test +import kotlin.test.assertContains +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith -class Version22Test : JvmBaseUnitTest() { +class Version22Test : BaseUnitTest() { private lateinit var db: Database - @Throws(Exception::class) override fun setUp() { super.setUp() db = openDatabaseResource("/databases/021.db") } - private val fileOpener = JavaFileOpener() - private fun migrateTo(version: Int) = runBlocking { db.migrateTo(version) { v -> val path = "migrations/%02d.sql".format(v) @@ -52,10 +47,10 @@ class Version22Test : JvmBaseUnitTest() { @Test fun testKeepValidReps() { val before = db.querySingle("select count(*) from repetitions") { it.getInt(0) } - assertThat(before, equalTo(3)) + assertEquals(3, before) migrateTo(22) val after = db.querySingle("select count(*) from repetitions") { it.getInt(0) } - assertThat(after, equalTo(3)) + assertEquals(3, after) } @Test @@ -64,21 +59,21 @@ class Version22Test : JvmBaseUnitTest() { val before = db.querySingle( "select count(*) from repetitions where habit = 99999" ) { it.getInt(0) } - assertThat(before, equalTo(1)) + assertEquals(1, before) migrateTo(22) val after = db.querySingle( "select count(*) from repetitions where habit = 99999" ) { it.getInt(0) } - assertThat(after, equalTo(0)) + assertEquals(0, after) } @Test fun testDisallowNewRepsWithInvalidRef() { migrateTo(22) - val exception = assertThrows(Exception::class.java) { + val exception = assertFailsWith { db.run("insert into Repetitions(habit, timestamp, value) values (99999, 100, 2)") } - assertThat(exception.message, Matchers.containsString("constraint")) + assertContains(exception.message!!, "constraint") } @Test @@ -87,21 +82,21 @@ class Version22Test : JvmBaseUnitTest() { val before = db.querySingle( "select count(*) from repetitions where timestamp is null" ) { it.getInt(0) } - assertThat(before, equalTo(1)) + assertEquals(1, before) migrateTo(22) val after = db.querySingle( "select count(*) from repetitions where timestamp is null" ) { it.getInt(0) } - assertThat(after, equalTo(0)) + assertEquals(0, after) } @Test fun testDisallowNullTimestamp() { migrateTo(22) - val exception = assertThrows(Exception::class.java) { + val exception = assertFailsWith { db.run("insert into Repetitions(habit, value) values (0, 2)") } - assertThat(exception.message, Matchers.containsString("constraint")) + assertContains(exception.message!!, "constraint") } @Test @@ -110,21 +105,21 @@ class Version22Test : JvmBaseUnitTest() { val before = db.querySingle( "select count(*) from repetitions where habit is null" ) { it.getInt(0) } - assertThat(before, equalTo(1)) + assertEquals(1, before) migrateTo(22) val after = db.querySingle( "select count(*) from repetitions where habit is null" ) { it.getInt(0) } - assertThat(after, equalTo(0)) + assertEquals(0, after) } @Test fun testDisallowNullHabit() { migrateTo(22) - val exception = assertThrows(Exception::class.java) { + val exception = assertFailsWith { db.run("insert into Repetitions(timestamp, value) values (5, 2)") } - assertThat(exception.message, Matchers.containsString("constraint")) + assertContains(exception.message!!, "constraint") } @Test @@ -135,21 +130,21 @@ class Version22Test : JvmBaseUnitTest() { val before = db.querySingle( "select count(*) from repetitions where timestamp=100 and habit=0" ) { it.getInt(0) } - assertThat(before, equalTo(3)) + assertEquals(3, before) migrateTo(22) val after = db.querySingle( "select count(*) from repetitions where timestamp=100 and habit=0" ) { it.getInt(0) } - assertThat(after, equalTo(1)) + assertEquals(1, after) } @Test fun testDisallowNewDuplicateTimestamps() { migrateTo(22) db.run("insert into repetitions(habit, timestamp, value)values (0, 100, 2)") - val exception = assertThrows(Exception::class.java) { + val exception = assertFailsWith { db.run("insert into repetitions(habit, timestamp, value)values (0, 100, 5)") } - assertThat(exception.message, Matchers.containsString("constraint")) + assertContains(exception.message!!, "constraint") } } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/migrations/Version23Test.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/database/migrations/Version23Test.kt similarity index 77% rename from uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/migrations/Version23Test.kt rename to uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/database/migrations/Version23Test.kt index a8a682d7..a02b8126 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/database/migrations/Version23Test.kt +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/database/migrations/Version23Test.kt @@ -20,16 +20,14 @@ package org.isoron.uhabits.core.database.migrations 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.JavaFileOpener import org.isoron.platform.io.migrateTo import org.isoron.platform.io.query -import org.isoron.uhabits.core.JvmBaseUnitTest -import org.junit.Test +import org.isoron.uhabits.core.BaseUnitTest +import kotlin.test.Test +import kotlin.test.assertEquals -class Version23Test : JvmBaseUnitTest() { +class Version23Test : BaseUnitTest() { private lateinit var db: Database @@ -38,8 +36,6 @@ class Version23Test : JvmBaseUnitTest() { db = openDatabaseResource("/databases/022.db") } - private val fileOpener = JavaFileOpener() - private fun migrateTo(version: Int) = runBlocking { db.migrateTo(version) { v -> val path = "migrations/%02d.sql".format(v) @@ -48,13 +44,13 @@ class Version23Test : JvmBaseUnitTest() { } @Test - fun `test migrate to 23 creates question column`() { + fun testMigrateTo23CreatesQuestionColumn() { migrateTo(23) db.query("select question from Habits") {} } @Test - fun `test migrate to 23 moves description to question column`() { + fun testMigrateTo23MovesDescriptionToQuestionColumn() { val descriptions = mutableListOf() db.query("select description from Habits") { stmt -> descriptions.add(stmt.getTextOrNull(0)) @@ -68,15 +64,15 @@ class Version23Test : JvmBaseUnitTest() { } for (i in descriptions.indices) { - assertThat(questions[i], equalTo(descriptions[i])) + assertEquals(descriptions[i], questions[i]) } } @Test - fun `test migrate to 23 sets description to null`() { + fun testMigrateTo23SetsDescriptionToNull() { migrateTo(23) db.query("select description from Habits") { stmt -> - assertThat(stmt.getTextOrNull(0), equalTo("")) + assertEquals("", stmt.getTextOrNull(0)) } } } diff --git a/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt new file mode 100644 index 00000000..96d74329 --- /dev/null +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2016-2025 Á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.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 = 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") + } + } +} diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/ImportTest.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/io/ImportTest.kt similarity index 58% rename from uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/ImportTest.kt rename to uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/io/ImportTest.kt index 273ee2c8..5aaff525 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/ImportTest.kt +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/io/ImportTest.kt @@ -19,39 +19,27 @@ package org.isoron.uhabits.core.io 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.uhabits.core.JvmBaseUnitTest +import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.HabitType -import org.junit.Before -import org.junit.Test -import java.io.File -import java.io.IOException +import kotlin.test.Test +import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue -class ImportTest : JvmBaseUnitTest() { - @Before - @Throws(Exception::class) - override fun setUp() { - super.setUp() - } +class ImportTest : BaseUnitTest() { @Test - @Throws(IOException::class) fun testHabitBullCSV() { importFromFile("habitbull.csv") - assertThat(habitList.size(), equalTo(4)) + assertEquals(4, habitList.size()) val habit = habitList.getByPosition(0) - assertThat(habit.name, equalTo("Breed dragons")) - assertThat(habit.description, equalTo("with love and fire")) - assertThat(habit.frequency, equalTo(Frequency.DAILY)) + assertEquals("Breed dragons", habit.name) + assertEquals("with love and fire", habit.description) + assertEquals(Frequency.DAILY, habit.frequency) assertTrue(isChecked(habit, 2016, 3, 18)) assertTrue(isChecked(habit, 2016, 3, 19)) assertFalse(isChecked(habit, 2016, 3, 20)) @@ -59,14 +47,13 @@ class ImportTest : JvmBaseUnitTest() { } @Test - @Throws(IOException::class) fun testHabitBullCSV2() { importFromFile("habitbull2.csv") - assertThat(habitList.size(), equalTo(6)) + assertEquals(6, habitList.size()) val habit = habitList.getByPosition(2) - assertThat(habit.name, equalTo("H3")) - assertThat(habit.description, equalTo("Habit 3")) - assertThat(habit.frequency, equalTo(Frequency.DAILY)) + assertEquals("H3", habit.name) + assertEquals("Habit 3", habit.description) + assertEquals(Frequency.DAILY, habit.frequency) assertTrue(isChecked(habit, 2019, 4, 11)) assertTrue(isChecked(habit, 2019, 5, 7)) assertFalse(isChecked(habit, 2019, 6, 14)) @@ -75,88 +62,83 @@ class ImportTest : JvmBaseUnitTest() { } @Test - @Throws(IOException::class) fun testHabitBullCSV3() { importFromFile("habitbull3.csv") - assertThat(habitList.size(), equalTo(2)) + assertEquals(2, habitList.size()) val habit = habitList.getByPosition(0) - assertThat(habit.name, equalTo("Pushups")) - assertThat(habit.type, equalTo(HabitType.NUMERICAL)) - assertThat(habit.description, equalTo("")) - assertThat(habit.frequency, equalTo(Frequency.DAILY)) - assertThat(getValue(habit, 2021, 9, 1), equalTo(30000)) - assertThat(getValue(habit, 2022, 1, 8), equalTo(100000)) + assertEquals("Pushups", habit.name) + assertEquals(HabitType.NUMERICAL, habit.type) + assertEquals("", habit.description) + assertEquals(Frequency.DAILY, habit.frequency) + assertEquals(30000, getValue(habit, 2021, 9, 1)) + assertEquals(100000, getValue(habit, 2022, 1, 8)) val habit2 = habitList.getByPosition(1) - assertThat(habit2.name, equalTo("run")) - assertThat(habit2.type, equalTo(HabitType.YES_NO)) - assertThat(habit2.description, equalTo("")) - assertThat(habit2.frequency, equalTo(Frequency.DAILY)) + assertEquals("run", habit2.name) + assertEquals(HabitType.YES_NO, habit2.type) + assertEquals("", habit2.description) + assertEquals(Frequency.DAILY, habit2.frequency) assertTrue(isChecked(habit2, 2022, 1, 3)) assertTrue(isChecked(habit2, 2022, 1, 18)) assertTrue(isChecked(habit2, 2022, 1, 19)) } @Test - @Throws(IOException::class) fun testHabitBullCSV4() { importFromFile("habitbull4.csv") - assertThat(habitList.size(), equalTo(1)) + assertEquals(1, habitList.size()) val habit = habitList.getByPosition(0) - assertThat(habit.name, equalTo("Caffeine")) - assertThat(habit.type, equalTo(HabitType.NUMERICAL)) - assertThat(habit.description, equalTo("")) - assertThat(habit.frequency, equalTo(Frequency.DAILY)) - assertThat(getValue(habit, 2022, 11, 21), equalTo(80000)) - assertThat(getValue(habit, 2022, 11, 22), equalTo(80000)) + assertEquals("Caffeine", habit.name) + assertEquals(HabitType.NUMERICAL, habit.type) + assertEquals("", habit.description) + assertEquals(Frequency.DAILY, habit.frequency) + assertEquals(80000, getValue(habit, 2022, 11, 21)) + assertEquals(80000, getValue(habit, 2022, 11, 22)) } @Test - @Throws(IOException::class) fun testLoopDB() { importFromFile("loop.db") - assertThat(habitList.size(), equalTo(9)) + assertEquals(9, habitList.size()) val habit = habitList.getByPosition(0) - assertThat(habit.name, equalTo("Wake up early")) - assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK)) + assertEquals("Wake up early", habit.name) + assertEquals(Frequency.THREE_TIMES_PER_WEEK, habit.frequency) assertTrue(isChecked(habit, 2016, 3, 14)) assertTrue(isChecked(habit, 2016, 3, 16)) assertFalse(isChecked(habit, 2016, 3, 17)) } @Test - @Throws(IOException::class) fun testRewireDB() { importFromFile("rewire.db") - assertThat(habitList.size(), equalTo(3)) + assertEquals(3, habitList.size()) var habit = habitList.getByPosition(1) - assertThat(habit.name, equalTo("Wake up early")) - assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK)) + assertEquals("Wake up early", habit.name) + assertEquals(Frequency.THREE_TIMES_PER_WEEK, habit.frequency) assertFalse(habit.hasReminder()) assertFalse(isChecked(habit, 2015, 12, 31)) assertTrue(isChecked(habit, 2016, 1, 18)) assertTrue(isChecked(habit, 2016, 1, 28)) assertFalse(isChecked(habit, 2016, 3, 10)) habit = habitList.getByPosition(2) - assertThat(habit.name, equalTo("brush teeth")) - assertThat(habit.frequency, equalTo(Frequency.THREE_TIMES_PER_WEEK)) - assertThat(habit.hasReminder(), equalTo(true)) + assertEquals("brush teeth", habit.name) + assertEquals(Frequency.THREE_TIMES_PER_WEEK, habit.frequency) + assertEquals(true, habit.hasReminder()) val reminder = habit.reminder - assertThat(reminder!!.hour, equalTo(8)) - assertThat(reminder.minute, equalTo(0)) + assertEquals(8, reminder!!.hour) + assertEquals(0, reminder.minute) val reminderDays = booleanArrayOf(false, true, true, true, true, true, false) - assertThat(reminder.days.toArray(), equalTo(reminderDays)) + assertEquals(reminderDays.toList(), reminder.days.toArray().toList()) } @Test - @Throws(IOException::class) fun testTickmateDB() { importFromFile("tickmate.db") - assertThat(habitList.size(), equalTo(3)) + assertEquals(3, habitList.size()) val h = habitList.getByPosition(2) - assertThat(h.name, equalTo("Vegan")) + assertEquals("Vegan", h.name) assertTrue(isChecked(h, 2016, 1, 24)) assertTrue(isChecked(h, 2016, 2, 5)) assertTrue(isChecked(h, 2016, 3, 18)) @@ -175,13 +157,9 @@ class ImportTest : JvmBaseUnitTest() { return h.originalEntries.get(LocalDate(year, month, day)).notes == notes } - @Throws(IOException::class) private fun importFromFile(assetFilename: String) = runBlocking { - val file = File.createTempFile("asset", "") - copyAssetToFile(assetFilename, file) - assertTrue(file.exists()) - assertTrue(file.canRead()) - val userFile = JavaUserFile(file.toPath()) + val userFile = copyResourceToTempFile(assetFilename) + assertTrue(userFile.exists()) val importer = GenericImporter( LoopDBImporter( habitList, @@ -189,7 +167,7 @@ class ImportTest : JvmBaseUnitTest() { databaseOpener, commandRunner, StandardLogging(), - JavaFileOpener() + fileOpener ), RewireDBImporter(habitList, modelFactory, databaseOpener), TickmateDBImporter(habitList, modelFactory, databaseOpener), @@ -197,6 +175,6 @@ class ImportTest : JvmBaseUnitTest() { ) assertTrue(importer.canHandle(userFile)) importer.importHabitsFromFile(userFile) - file.delete() + userFile.delete() } } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.kt similarity index 80% rename from uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.kt rename to uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.kt index 811841b6..3e882c46 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.kt +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.kt @@ -20,9 +20,7 @@ package org.isoron.uhabits.core.models.sqlite import dev.mokkery.mock import dev.mokkery.verify -import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.MatcherAssert.assertThat -import org.isoron.uhabits.core.JvmBaseUnitTest +import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.database.HabitRepository import org.isoron.uhabits.core.models.Habit 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.WeekdayList import org.isoron.uhabits.core.test.HabitFixtures -import org.junit.After -import org.junit.Assert.assertThrows -import org.junit.Test -import java.util.ArrayList +import kotlin.test.AfterTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith import kotlin.test.assertNull -class SQLiteHabitListTest : JvmBaseUnitTest() { +class SQLiteHabitListTest : BaseUnitTest() { private lateinit var repository: HabitRepository private var listener: ModelObservable.Listener = mock() private lateinit var habitsArray: ArrayList private lateinit var activeHabits: HabitList private lateinit var reminderHabits: HabitList - @Throws(Exception::class) override fun setUp() { super.setUp() val db = buildMemoryDatabase() @@ -75,7 +72,7 @@ class SQLiteHabitListTest : JvmBaseUnitTest() { habitList.observable.addListener(listener) } - @After + @AfterTest fun tearDown() { habitList.observable.removeListener(listener) } @@ -85,7 +82,7 @@ class SQLiteHabitListTest : JvmBaseUnitTest() { val habit = modelFactory.buildHabit() habitList.add(habit) verify { listener.onModelChange() } - assertThrows(IllegalArgumentException::class.java) { + assertFailsWith { habitList.add(habit) } } @@ -96,10 +93,10 @@ class SQLiteHabitListTest : JvmBaseUnitTest() { habit.name = "Hello world with id" habit.id = 12300L habitList.add(habit) - assertThat(habit.id, equalTo(12300L)) + assertEquals(12300L, habit.id) val all = repository.findAll() val record = all.find { it.id == 12300L } - assertThat(record!!.name, equalTo(habit.name)) + assertEquals(habit.name, record!!.name) } @Test @@ -110,20 +107,20 @@ class SQLiteHabitListTest : JvmBaseUnitTest() { habitList.add(habit) val all = repository.findAll() val record = all.find { it.id == habit.id } - assertThat(record!!.name, equalTo(habit.name)) + assertEquals(habit.name, record!!.name) } @Test fun testSize() { - assertThat(habitList.size(), equalTo(10)) + assertEquals(10, habitList.size()) } @Test fun testGetById() { val h1 = habitList.getById(1)!! - assertThat(h1.name, equalTo("habit 1")) + assertEquals("habit 1", h1.name) val h2 = habitList.getById(2)!! - assertThat(h2, equalTo(h2)) + assertEquals(h2, h2) } @Test @@ -136,31 +133,30 @@ class SQLiteHabitListTest : JvmBaseUnitTest() { @Test fun testGetByPosition() { val h = habitList.getByPosition(4) - assertThat(h.name, equalTo("habit 5")) + assertEquals("habit 5", h.name) } @Test fun testIndexOf() { val h1 = habitList.getByPosition(5) - assertThat(habitList.indexOf(h1), equalTo(5)) + assertEquals(5, habitList.indexOf(h1)) val h2 = modelFactory.buildHabit() - assertThat(habitList.indexOf(h2), equalTo(-1)) + assertEquals(-1, habitList.indexOf(h2)) h2.id = 1000L - assertThat(habitList.indexOf(h2), equalTo(-1)) + assertEquals(-1, habitList.indexOf(h2)) } @Test - @Throws(Exception::class) fun testRemove() { val h = habitList.getById(2) habitList.remove(h!!) - assertThat(habitList.indexOf(h), equalTo(-1)) + assertEquals(-1, habitList.indexOf(h)) val all = repository.findAll() val rec2 = all.find { it.id == 2L } assertNull(rec2) val rec3 = all.find { it.id == 3L }!! - assertThat(rec3.position, equalTo(1)) + assertEquals(1, rec3.position) } @Test @@ -168,13 +164,13 @@ class SQLiteHabitListTest : JvmBaseUnitTest() { habitList.primaryOrder = HabitList.Order.BY_NAME_DESC val h = habitList.getById(2) habitList.remove(h!!) - assertThat(habitList.indexOf(h), equalTo(-1)) + assertEquals(-1, habitList.indexOf(h)) val all = repository.findAll() val rec2 = all.find { it.id == 2L } assertNull(rec2) val rec3 = all.find { it.id == 3L }!! - assertThat(rec3.position, equalTo(1)) + assertEquals(1, rec3.position) } @Test @@ -184,8 +180,8 @@ class SQLiteHabitListTest : JvmBaseUnitTest() { habitList.reorder(habit4, habit3) val all = repository.findAll() val record3 = all.find { it.id == 3L }!! - assertThat(record3.position, equalTo(3)) + assertEquals(3, record3.position) val record4 = all.find { it.id == 4L }!! - assertThat(record4.position, equalTo(2)) + assertEquals(2, record4.position) } } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt similarity index 81% rename from uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt rename to uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt index 5c4737ea..1e2cdaf9 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt @@ -25,24 +25,22 @@ import dev.mokkery.every import dev.mokkery.matcher.any import dev.mokkery.mock import dev.mokkery.resetCalls +import dev.mokkery.spy import dev.mokkery.verify -import org.apache.commons.io.FileUtils -import org.hamcrest.MatcherAssert.assertThat -import org.hamcrest.core.IsEqual.equalTo -import org.isoron.platform.io.JavaUserFile +import kotlinx.coroutines.runBlocking +import org.isoron.platform.io.UserFile 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.Habit import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.ui.callbacks.NumberPickerCallback -import org.junit.Before -import org.junit.Test -import java.nio.file.Files +import kotlin.test.Test +import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue -class ListHabitsBehaviorTest : JvmBaseUnitTest() { +class ListHabitsBehaviorTest : BaseUnitTest() { private val dirFinder: ListHabitsBehavior.DirFinder = mock() private val prefs: Preferences = mock() @@ -56,15 +54,13 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() { private val bugReporter: ListHabitsBehavior.BugReporter = mock() - @Before - @Throws(Exception::class) override fun setUp() { super.setUp() habit1 = fixtures.createShortHabit() habit2 = fixtures.createNumericalHabit() habitList.add(habit1) habitList.add(habit2) - resetCalls(habitList) + habitList = spy(habitList) behavior = ListHabitsBehavior( habitList, dirFinder, @@ -90,29 +86,26 @@ class ListHabitsBehaviorTest : JvmBaseUnitTest() { screen.showNumberPopup(0.1, "", any()) } capturedPicker!!.onNumberPicked(100.0, "") - assertThat(habit2.computedEntries.get(today).value, equalTo(100000)) + assertEquals(100000, habit2.computedEntries.get(today).value) } @Test - @Throws(Exception::class) fun testOnExportCSV() { - val outputDir = Files.createTempDirectory("CSV").toFile() - every { dirFinder.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath()) + val outputDir = createTempDir() + every { dirFinder.getCSVOutputDir() } returns outputDir behavior.onExportCSV() verify { screen.showSendFileScreen(any()) } - assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1)) - FileUtils.deleteDirectory(outputDir) + val files = runBlocking { outputDir.listFiles() } + assertEquals(1, files!!.size) } @Test - @Throws(Exception::class) fun testOnExportCSV_fail() { - val outputDir = Files.createTempDirectory("CSV").toFile() - outputDir.setWritable(false) - every { dirFinder.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath()) + val mockDir: UserFile = mock() + every { mockDir.resolve(any()) } throws RuntimeException("not writable") + every { dirFinder.getCSVOutputDir() } returns mockDir behavior.onExportCSV() verify { screen.showMessage(ListHabitsBehavior.Message.COULD_NOT_EXPORT) } - assertTrue(outputDir.delete()) } @Test diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.kt similarity index 72% rename from uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.kt rename to uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.kt index baa5d99e..87087e0a 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.kt +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitMenuPresenterTest.kt @@ -22,22 +22,18 @@ import dev.mokkery.answering.returns import dev.mokkery.every import dev.mokkery.mock import dev.mokkery.verify -import org.apache.commons.io.FileUtils -import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.MatcherAssert.assertThat -import org.isoron.platform.io.JavaUserFile -import org.isoron.uhabits.core.JvmBaseUnitTest +import kotlinx.coroutines.runBlocking +import org.isoron.uhabits.core.BaseUnitTest import org.isoron.uhabits.core.models.Habit -import org.junit.Test -import java.nio.file.Files +import kotlin.test.Test +import kotlin.test.assertEquals -class ShowHabitMenuPresenterTest : JvmBaseUnitTest() { +class ShowHabitMenuPresenterTest : BaseUnitTest() { private lateinit var system: ShowHabitMenuPresenter.System private lateinit var screen: ShowHabitMenuPresenter.Screen private lateinit var habit: Habit private lateinit var menu: ShowHabitMenuPresenter - @Throws(Exception::class) override fun setUp() { super.setUp() system = mock() @@ -60,12 +56,11 @@ class ShowHabitMenuPresenterTest : JvmBaseUnitTest() { } @Test - @Throws(Exception::class) fun testOnExport() { - val outputDir = Files.createTempDirectory("CSV").toFile() - every { system.getCSVOutputDir() } returns JavaUserFile(outputDir.toPath()) + val outputDir = createTempDir() + every { system.getCSVOutputDir() } returns outputDir menu.onExportCSV() - assertThat(FileUtils.listFiles(outputDir, null, false).size, equalTo(1)) - FileUtils.deleteDirectory(outputDir) + val files = runBlocking { outputDir.listFiles() } + assertEquals(1, files!!.size) } } diff --git a/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/utils/FileExtensionsTest.kt b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/utils/FileExtensionsTest.kt new file mode 100644 index 00000000..2b3bc4b1 --- /dev/null +++ b/uhabits-core/src/commonTest/kotlin/org/isoron/uhabits/core/utils/FileExtensionsTest.kt @@ -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) + } +} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/platform/io/JavaFiles.kt b/uhabits-core/src/jvmMain/java/org/isoron/platform/io/JavaFiles.kt index ac8bd0f9..ed2db39b 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/platform/io/JavaFiles.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/platform/io/JavaFiles.kt @@ -103,6 +103,15 @@ class JavaUserFile(val path: Path) : UserFile { override fun resolve(child: String): UserFile { return JavaUserFile(path.resolve(child)) } + + override suspend fun listFiles(): List? { + val files = path.toFile().listFiles() ?: return null + return files.map { JavaUserFile(it.toPath()) } + } + + override suspend fun mkdirs() { + path.toFile().mkdirs() + } } @Suppress("NewApi") diff --git a/uhabits-core/src/jvmMain/java/org/isoron/platform/io/ZipReader.kt b/uhabits-core/src/jvmMain/java/org/isoron/platform/io/ZipReader.kt new file mode 100644 index 00000000..cb4ea7f1 --- /dev/null +++ b/uhabits-core/src/jvmMain/java/org/isoron/platform/io/ZipReader.kt @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016-2025 Á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.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 { + val result = mutableListOf() + 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 + } +} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/platform/io/ZipWriter.kt b/uhabits-core/src/jvmMain/java/org/isoron/platform/io/ZipWriter.kt index 33ad8c5d..876083b9 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/platform/io/ZipWriter.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/platform/io/ZipWriter.kt @@ -20,7 +20,6 @@ package org.isoron.platform.io import java.io.ByteArrayOutputStream -import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream actual class ZipWriter { @@ -28,7 +27,7 @@ actual class ZipWriter { private val zos = ZipOutputStream(baos) actual fun addEntry(name: String, content: String) { - zos.putNextEntry(ZipEntry(name)) + zos.putNextEntry(java.util.zip.ZipEntry(name)) zos.write(content.toByteArray()) zos.closeEntry() } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/platform/io/TestPlatformHelper.kt b/uhabits-core/src/jvmTest/java/org/isoron/platform/io/TestPlatformHelper.kt new file mode 100644 index 00000000..8515f97d --- /dev/null +++ b/uhabits-core/src/jvmTest/java/org/isoron/platform/io/TestPlatformHelper.kt @@ -0,0 +1,4 @@ +package org.isoron.platform.io + +actual fun createTestFileOpener(): FileOpener = JavaFileOpener() +actual fun createTestDatabaseOpener(): DatabaseOpener = JavaDatabaseOpener() diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/JvmBaseUnitTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/JvmBaseUnitTest.kt index 7f07f51c..6e61faac 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/JvmBaseUnitTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/JvmBaseUnitTest.kt @@ -20,7 +20,6 @@ package org.isoron.uhabits.core import dev.mokkery.spy import org.apache.commons.io.IOUtils -import org.isoron.platform.io.JavaDatabaseOpener import org.isoron.uhabits.core.models.memory.MemoryModelFactory import org.isoron.uhabits.core.test.HabitFixtures import org.junit.Before @@ -35,8 +34,6 @@ import java.util.GregorianCalendar import java.util.TimeZone open class JvmBaseUnitTest : BaseUnitTest() { - protected var databaseOpener: org.isoron.platform.io.DatabaseOpener = JavaDatabaseOpener() - @Before override fun setUp() { super.setUp() @@ -75,13 +72,4 @@ open class JvmBaseUnitTest : BaseUnitTest() { if (inputStream != null) return inputStream 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) - } } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt deleted file mode 100644 index 3883687b..00000000 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/io/HabitsCSVExporterTest.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2016-2025 Á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.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 = 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") - } -} diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/utils/FileExtensionsTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/utils/FileExtensionsTest.kt deleted file mode 100644 index 76cbad0e..00000000 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/utils/FileExtensionsTest.kt +++ /dev/null @@ -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) - } -}