Remove JvmBaseUnitTest and move chart and DateUtils tests to commonTest

This commit is contained in:
Alinson S. Xavier 2026-04-08 06:13:43 -05:00
parent a93e871daf
commit 9cf4ec417c
13 changed files with 93 additions and 127 deletions

View File

@ -0,0 +1,43 @@
package org.isoron.platform.gui
import org.isoron.platform.io.createTestCanvas
import org.isoron.platform.io.createTestFileOpener
import kotlin.test.fail
suspend fun assertRenders(
path: String,
canvas: Canvas
) {
val actualImage = canvas.toImage()
val failedActualPath = "/tmp/failed/$path"
val failedExpectedPath = failedActualPath.replace(".png", ".expected.png")
val failedDiffPath = failedActualPath.replace(".png", ".diff.png")
val fileOpener = createTestFileOpener()
val expectedFile = fileOpener.openResourceFile(path)
if (expectedFile.exists()) {
val expectedImage = expectedFile.toImage()
val diffImage = expectedFile.toImage()
diffImage.diff(actualImage)
val distance = diffImage.averageLuminosity * 100
if (distance >= 1.0) {
expectedImage.export(failedExpectedPath)
actualImage.export(failedActualPath)
diffImage.export(failedDiffPath)
fail("Images differ (distance=$distance)")
}
} else {
actualImage.export(failedActualPath)
fail("Expected image file is missing. Actual image: $failedActualPath")
}
}
suspend fun assertRenders(
width: Int,
height: Int,
expectedPath: String,
view: View
) {
val canvas = createTestCanvas(width, height)
view.draw(canvas)
assertRenders(expectedPath, canvas)
}

View File

@ -1,4 +1,9 @@
package org.isoron.platform.io
import org.isoron.platform.gui.Canvas
import org.isoron.platform.time.LocalDateFormatter
expect fun createTestFileOpener(): FileOpener
expect fun createTestDatabaseOpener(): DatabaseOpener
expect fun createTestCanvas(width: Int, height: Int): Canvas
expect fun createTestDateFormatter(): LocalDateFormatter

View File

@ -23,9 +23,9 @@ 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.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
import kotlin.test.assertEquals
class HabitsCSVExporterTest : BaseUnitTest() {

View File

@ -24,7 +24,6 @@ import dev.mokkery.answering.throws
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 kotlinx.coroutines.runBlocking

View File

@ -21,15 +21,14 @@ package org.isoron.uhabits.core.ui.views
import kotlinx.coroutines.runBlocking
import org.isoron.platform.gui.assertRenders
import org.isoron.platform.time.JavaLocalDateFormatter
import org.isoron.platform.io.createTestDateFormatter
import org.isoron.platform.time.LocalDate
import org.junit.Test
import java.util.Locale
import kotlin.test.Test
class BarChartTest {
val base = "views/BarChart"
val today = LocalDate(2015, 1, 25)
private val fmt = JavaLocalDateFormatter(Locale.US)
private val fmt = createTestDateFormatter()
val theme = LightTheme()
val component = BarChart(theme, fmt)
private val axis = (0..100).map { today.minus(it) }

View File

@ -25,17 +25,16 @@ import dev.mokkery.verify
import dev.mokkery.verifyNoMoreCalls
import kotlinx.coroutines.runBlocking
import org.isoron.platform.gui.assertRenders
import org.isoron.platform.io.createTestDateFormatter
import org.isoron.platform.time.DayOfWeek
import org.isoron.platform.time.DayOfWeek.SUNDAY
import org.isoron.platform.time.JavaLocalDateFormatter
import org.isoron.platform.time.LocalDate
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.views.HistoryChart.Square.DIMMED
import org.isoron.uhabits.core.ui.views.HistoryChart.Square.HATCHED
import org.isoron.uhabits.core.ui.views.HistoryChart.Square.OFF
import org.isoron.uhabits.core.ui.views.HistoryChart.Square.ON
import org.junit.Test
import java.util.Locale
import kotlin.test.Test
class HistoryChartTest {
val base = "views/HistoryChart"
@ -46,7 +45,7 @@ class HistoryChartTest {
today = LocalDate(2015, 1, 25),
paletteColor = PaletteColor(7),
theme = LightTheme(),
dateFormatter = JavaLocalDateFormatter(Locale.US),
dateFormatter = createTestDateFormatter(),
firstWeekday = SUNDAY,
onDateClickedListener = dateClickedListener,
defaultSquare = OFF,

View File

@ -33,9 +33,9 @@ class JavaCanvasTest {
}
}
fun createCanvas(w: Int, h: Int) = JavaCanvas(BufferedImage(2 * w, 2 * h, TYPE_INT_ARGB), 2.0)
private fun createCanvas(w: Int, h: Int) = JavaCanvas(BufferedImage(2 * w, 2 * h, TYPE_INT_ARGB), 2.0)
suspend fun assertRenders(
private suspend fun assertRenders(
path: String,
canvas: Canvas
) {
@ -65,7 +65,7 @@ suspend fun assertRenders(
}
}
suspend fun assertRenders(
private suspend fun assertRenders(
width: Int,
height: Int,
expectedPath: String,

View File

@ -1,4 +1,20 @@
package org.isoron.platform.io
import org.isoron.platform.gui.Canvas
import org.isoron.platform.gui.JavaCanvas
import org.isoron.platform.time.JavaLocalDateFormatter
import org.isoron.platform.time.LocalDateFormatter
import java.awt.image.BufferedImage
import java.awt.image.BufferedImage.TYPE_INT_ARGB
import java.util.Locale
actual fun createTestFileOpener(): FileOpener = JavaFileOpener()
actual fun createTestDatabaseOpener(): DatabaseOpener = JavaDatabaseOpener()
actual fun createTestCanvas(width: Int, height: Int): Canvas {
return JavaCanvas(BufferedImage(2 * width, 2 * height, TYPE_INT_ARGB), 2.0)
}
actual fun createTestDateFormatter(): LocalDateFormatter {
return JavaLocalDateFormatter(Locale.US)
}

View File

@ -1,29 +1,9 @@
/*
* 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.utils
package org.isoron.platform.time
import org.isoron.platform.time.DateUtils
import org.junit.After
import org.junit.Before
import org.junit.Test
import java.util.Calendar
import java.util.GregorianCalendar
import java.util.TimeZone
import kotlin.test.assertEquals
@ -45,13 +25,6 @@ class DateUtilsTest {
DateUtils.setFixedTimeZone(null)
}
private fun unixTime(year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0): Long {
val cal = GregorianCalendar(TimeZone.getTimeZone("GMT"))
cal.set(year, month, day, hour, minute, 0)
cal.set(GregorianCalendar.MILLISECOND, 0)
return cal.timeInMillis
}
// ---------------------------------------------------------------
// getLocalTime
// ---------------------------------------------------------------

View File

@ -0,0 +1,11 @@
package org.isoron.platform.time
import java.util.GregorianCalendar
import java.util.TimeZone
fun unixTime(year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0, milliseconds: Long = 0): Long {
val cal = GregorianCalendar(TimeZone.getTimeZone("GMT"))
cal.set(year, month, day, hour, minute, 0)
cal.set(GregorianCalendar.MILLISECOND, 0)
return cal.timeInMillis + milliseconds
}

View File

@ -1,75 +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
import dev.mokkery.spy
import org.apache.commons.io.IOUtils
import org.isoron.uhabits.core.models.memory.MemoryModelFactory
import org.isoron.uhabits.core.test.HabitFixtures
import org.junit.Before
import org.junit.Test
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.nio.file.Paths
import java.util.GregorianCalendar
import java.util.TimeZone
open class JvmBaseUnitTest : BaseUnitTest() {
@Before
override fun setUp() {
super.setUp()
habitList = spy(habitList)
fixtures = HabitFixtures(modelFactory as MemoryModelFactory, habitList)
}
fun unixTime(year: Int, month: Int, day: Int): Long {
return unixTime(year, month, day, 0, 0)
}
open fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int, milliseconds: Long = 0): Long {
val cal = GregorianCalendar(TimeZone.getTimeZone("GMT"))
cal.set(year, month, day, hour, minute, 0)
cal.set(GregorianCalendar.MILLISECOND, 0)
return cal.timeInMillis + milliseconds
}
@Test
fun nothing() {
}
@Throws(IOException::class)
protected fun copyAssetToFile(assetPath: String, dst: File?) {
IOUtils.copy(openAsset(assetPath), FileOutputStream(dst!!))
}
@Throws(IOException::class)
protected fun openAsset(assetPath: String): InputStream {
var inputStream = javaClass.getResourceAsStream(assetPath)
if (inputStream != null) return inputStream
val pwd = Paths.get(".").toAbsolutePath().normalize().toString()
val fullPath = "$pwd/assets/test/$assetPath"
val file = File(fullPath)
if (file.exists() && file.canRead()) inputStream = FileInputStream(file)
if (inputStream != null) return inputStream
throw IllegalStateException("asset not found: $fullPath")
}
}

View File

@ -27,7 +27,8 @@ import org.isoron.platform.time.DateUtils
import org.isoron.platform.time.DateUtils.removeTimezone
import org.isoron.platform.time.DateUtils.setFixedLocalTime
import org.isoron.platform.time.DateUtils.setFixedTimeZone
import org.isoron.uhabits.core.JvmBaseUnitTest
import org.isoron.platform.time.unixTime
import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.WeekdayList
@ -37,7 +38,7 @@ import org.junit.Before
import org.junit.Test
import java.util.TimeZone
class ReminderSchedulerTest : JvmBaseUnitTest() {
class ReminderSchedulerTest : BaseUnitTest() {
private val habitId = 10L
private lateinit var habit: Habit
private lateinit var reminderScheduler: ReminderScheduler
@ -145,13 +146,6 @@ class ReminderSchedulerTest : JvmBaseUnitTest() {
reminderScheduler.schedule(habit)
}
override fun unixTime(year: Int, month: Int, day: Int, hour: Int, minute: Int, milliseconds: Long): Long {
val cal = java.util.GregorianCalendar(TimeZone.getTimeZone("GMT"))
cal.set(year, month, day, hour, minute, 0)
cal.set(java.util.GregorianCalendar.MILLISECOND, 0)
return cal.timeInMillis
}
private fun scheduleAndVerify(
atTime: Long?,
expectedCheckmarkTime: Long,

View File

@ -5,7 +5,8 @@ import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.isoron.platform.time.DateUtils
import org.isoron.uhabits.core.JvmBaseUnitTest
import org.isoron.platform.time.unixTime
import org.isoron.uhabits.core.BaseUnitTest
import org.isoron.uhabits.core.io.StandardLogging
import org.isoron.uhabits.core.preferences.Preferences
import org.junit.After
@ -17,7 +18,7 @@ import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlin.test.assertEquals
class MidnightTimerTest : JvmBaseUnitTest() {
class MidnightTimerTest : BaseUnitTest() {
@After
fun tearDown() {
@ -56,4 +57,5 @@ class MidnightTimerTest : JvmBaseUnitTest() {
assertEquals(true, suspendedListener)
}
}
}