mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Make I/O asynchronous with coroutines; make all JS tests pass
This commit is contained in:
@@ -53,6 +53,7 @@ kotlin {
|
|||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('stdlib-common')
|
implementation kotlin('stdlib-common')
|
||||||
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.2.0-alpha-2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ kotlin {
|
|||||||
jvmMain {
|
jvmMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('stdlib-jdk8')
|
implementation kotlin('stdlib-jdk8')
|
||||||
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0-alpha-2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +82,7 @@ kotlin {
|
|||||||
jsMain {
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('stdlib-js')
|
implementation kotlin('stdlib-js')
|
||||||
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.2.0-alpha-2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ fun Database.getVersion() = queryInt("pragma user_version")
|
|||||||
|
|
||||||
fun Database.setVersion(v: Int) = run("pragma user_version = $v")
|
fun Database.setVersion(v: Int) = run("pragma user_version = $v")
|
||||||
|
|
||||||
fun Database.migrateTo(newVersion: Int, fileOpener: FileOpener, log: Log) {
|
suspend fun Database.migrateTo(newVersion: Int, fileOpener: FileOpener, log: Log) {
|
||||||
val currentVersion = getVersion()
|
val currentVersion = getVersion()
|
||||||
log.debug("Database", "Current database version: $currentVersion")
|
log.debug("Database", "Current database version: $currentVersion")
|
||||||
|
|
||||||
@@ -92,9 +92,11 @@ fun Database.migrateTo(newVersion: Int, fileOpener: FileOpener, log: Log) {
|
|||||||
|
|
||||||
begin()
|
begin()
|
||||||
for (v in (currentVersion + 1)..newVersion) {
|
for (v in (currentVersion + 1)..newVersion) {
|
||||||
val filename = sprintf("migrations/%03d.sql", v)
|
val sv = if(v < 10) "00$v" else if (v<100) "0$v" else "$v"
|
||||||
|
val filename = "migrations/$sv.sql"
|
||||||
|
println(filename)
|
||||||
val migrationFile = fileOpener.openResourceFile(filename)
|
val migrationFile = fileOpener.openResourceFile(filename)
|
||||||
for (line in migrationFile.readLines()) {
|
for (line in migrationFile.lines()) {
|
||||||
if (line.isEmpty()) continue
|
if (line.isEmpty()) continue
|
||||||
run(line)
|
run(line)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,6 @@ interface UserFile {
|
|||||||
* files or translations. These files cannot be deleted.
|
* files or translations. These files cannot be deleted.
|
||||||
*/
|
*/
|
||||||
interface ResourceFile {
|
interface ResourceFile {
|
||||||
fun readLines(): List<String>
|
|
||||||
fun copyTo(dest: UserFile)
|
fun copyTo(dest: UserFile)
|
||||||
|
suspend fun lines(): List<String>
|
||||||
}
|
}
|
||||||
@@ -29,11 +29,11 @@ interface Log {
|
|||||||
*/
|
*/
|
||||||
class StandardLog : Log {
|
class StandardLog : Log {
|
||||||
override fun info(tag: String, msg: String) {
|
override fun info(tag: String, msg: String) {
|
||||||
println(sprintf("I/%-20s %s", tag, msg))
|
println("I/$tag $msg")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun debug(tag: String, msg: String) {
|
override fun debug(tag: String, msg: String) {
|
||||||
println(sprintf("D/%-20s %s", tag, msg))
|
println("D/$tag $msg")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -26,82 +26,82 @@ import org.isoron.uhabits.components.*
|
|||||||
import org.isoron.uhabits.i18n.*
|
import org.isoron.uhabits.i18n.*
|
||||||
import org.isoron.uhabits.models.*
|
import org.isoron.uhabits.models.*
|
||||||
|
|
||||||
class Backend(databaseName: String,
|
//class Backend(databaseName: String,
|
||||||
databaseOpener: DatabaseOpener,
|
// databaseOpener: DatabaseOpener,
|
||||||
fileOpener: FileOpener,
|
// fileOpener: FileOpener,
|
||||||
localeHelper: LocaleHelper,
|
// localeHelper: LocaleHelper,
|
||||||
val log: Log,
|
// val log: Log,
|
||||||
val taskRunner: TaskRunner) {
|
// val taskRunner: TaskRunner) {
|
||||||
|
//
|
||||||
val database: Database
|
// val database: Database
|
||||||
|
//
|
||||||
val habitsRepository: HabitRepository
|
// val habitsRepository: HabitRepository
|
||||||
|
//
|
||||||
val checkmarkRepository: CheckmarkRepository
|
// val checkmarkRepository: CheckmarkRepository
|
||||||
|
//
|
||||||
val habits = mutableMapOf<Int, Habit>()
|
// val habits = mutableMapOf<Int, Habit>()
|
||||||
|
//
|
||||||
val checkmarks = mutableMapOf<Habit, CheckmarkList>()
|
// val checkmarks = mutableMapOf<Habit, CheckmarkList>()
|
||||||
|
//
|
||||||
val scores = mutableMapOf<Habit, ScoreList>()
|
// val scores = mutableMapOf<Habit, ScoreList>()
|
||||||
|
//
|
||||||
val mainScreenDataSource: MainScreenDataSource
|
// val mainScreenDataSource: MainScreenDataSource
|
||||||
|
//
|
||||||
val strings = localeHelper.getStringsForCurrentLocale()
|
// val strings = localeHelper.getStringsForCurrentLocale()
|
||||||
|
//
|
||||||
val preferences: Preferences
|
// val preferences: Preferences
|
||||||
|
//
|
||||||
var theme: Theme = LightTheme()
|
// var theme: Theme = LightTheme()
|
||||||
|
//
|
||||||
init {
|
// init {
|
||||||
val dbFile = fileOpener.openUserFile(databaseName)
|
// val dbFile = fileOpener.openUserFile(databaseName)
|
||||||
if (!dbFile.exists()) {
|
// if (!dbFile.exists()) {
|
||||||
val templateFile = fileOpener.openResourceFile("databases/template.db")
|
// val templateFile = fileOpener.openResourceFile("databases/template.db")
|
||||||
templateFile.copyTo(dbFile)
|
// templateFile.copyTo(dbFile)
|
||||||
}
|
// }
|
||||||
database = databaseOpener.open(dbFile)
|
// database = databaseOpener.open(dbFile)
|
||||||
database.migrateTo(LOOP_DATABASE_VERSION, fileOpener, log)
|
// database.migrateTo(LOOP_DATABASE_VERSION, fileOpener, log)
|
||||||
preferences = Preferences(PreferencesRepository(database))
|
// preferences = Preferences(PreferencesRepository(database))
|
||||||
habitsRepository = HabitRepository(database)
|
// habitsRepository = HabitRepository(database)
|
||||||
checkmarkRepository = CheckmarkRepository(database)
|
// checkmarkRepository = CheckmarkRepository(database)
|
||||||
taskRunner.runInBackground {
|
// taskRunner.runInBackground {
|
||||||
habits.putAll(habitsRepository.findAll())
|
// habits.putAll(habitsRepository.findAll())
|
||||||
for ((key, habit) in habits) {
|
// for ((key, habit) in habits) {
|
||||||
val checks = checkmarkRepository.findAll(key)
|
// val checks = checkmarkRepository.findAll(key)
|
||||||
checkmarks[habit] = CheckmarkList(habit.frequency, habit.type)
|
// checkmarks[habit] = CheckmarkList(habit.frequency, habit.type)
|
||||||
checkmarks[habit]?.setManualCheckmarks(checks)
|
// checkmarks[habit]?.setManualCheckmarks(checks)
|
||||||
scores[habit] = ScoreList(checkmarks[habit]!!)
|
// scores[habit] = ScoreList(checkmarks[habit]!!)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
mainScreenDataSource = MainScreenDataSource(preferences,
|
// mainScreenDataSource = MainScreenDataSource(preferences,
|
||||||
habits,
|
// habits,
|
||||||
checkmarks,
|
// checkmarks,
|
||||||
scores,
|
// scores,
|
||||||
taskRunner)
|
// taskRunner)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun createHabit(habit: Habit) {
|
// fun createHabit(habit: Habit) {
|
||||||
val id = habitsRepository.nextId()
|
// val id = habitsRepository.nextId()
|
||||||
habit.id = id
|
// habit.id = id
|
||||||
habit.position = habits.size
|
// habit.position = habits.size
|
||||||
habits[id] = habit
|
// habits[id] = habit
|
||||||
checkmarks[habit] = CheckmarkList(habit.frequency, habit.type)
|
// checkmarks[habit] = CheckmarkList(habit.frequency, habit.type)
|
||||||
habitsRepository.insert(habit)
|
// habitsRepository.insert(habit)
|
||||||
mainScreenDataSource.requestData()
|
// mainScreenDataSource.requestData()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun deleteHabit(id: Int) {
|
// fun deleteHabit(id: Int) {
|
||||||
habits[id]?.let { habit ->
|
// habits[id]?.let { habit ->
|
||||||
habitsRepository.delete(habit)
|
// habitsRepository.delete(habit)
|
||||||
habits.remove(id)
|
// habits.remove(id)
|
||||||
mainScreenDataSource.requestData()
|
// mainScreenDataSource.requestData()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun updateHabit(modified: Habit) {
|
// fun updateHabit(modified: Habit) {
|
||||||
habits[modified.id]?.let { existing ->
|
// habits[modified.id]?.let { existing ->
|
||||||
modified.position = existing.position
|
// modified.position = existing.position
|
||||||
habitsRepository.update(modified)
|
// habitsRepository.update(modified)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -22,5 +22,4 @@ package org.isoron
|
|||||||
open class BaseTest {
|
open class BaseTest {
|
||||||
val resolver = DependencyResolver()
|
val resolver = DependencyResolver()
|
||||||
val fileOpener = resolver.getFileOpener()
|
val fileOpener = resolver.getFileOpener()
|
||||||
val db = resolver.getDatabase()
|
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ import org.isoron.platform.io.*
|
|||||||
|
|
||||||
expect class DependencyResolver() {
|
expect class DependencyResolver() {
|
||||||
fun getFileOpener(): FileOpener
|
fun getFileOpener(): FileOpener
|
||||||
fun getDatabase(): Database
|
suspend fun getDatabase(): Database
|
||||||
fun createCanvas(width: Int, height: Int): Canvas
|
fun createCanvas(width: Int, height: Int): Canvas
|
||||||
fun exportCanvas(canvas: Canvas, filename: String)
|
fun exportCanvas(canvas: Canvas, filename: String)
|
||||||
}
|
}
|
||||||
@@ -23,8 +23,8 @@ import org.isoron.*
|
|||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
class DatabaseTest() : BaseTest() {
|
class DatabaseTest() : BaseTest() {
|
||||||
@Test
|
suspend fun testUsage() {
|
||||||
fun testUsage() {
|
val db = resolver.getDatabase()
|
||||||
db.setVersion(0)
|
db.setVersion(0)
|
||||||
assertEquals(0, db.getVersion())
|
assertEquals(0, db.getVersion())
|
||||||
|
|
||||||
|
|||||||
@@ -23,15 +23,14 @@ import org.isoron.*
|
|||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
class FilesTest() : BaseTest() {
|
class FilesTest() : BaseTest() {
|
||||||
@Test
|
suspend fun testLines() {
|
||||||
fun testReadLines() {
|
|
||||||
val hello = fileOpener.openResourceFile("hello.txt")
|
val hello = fileOpener.openResourceFile("hello.txt")
|
||||||
var lines = hello.readLines()
|
var lines = hello.lines()
|
||||||
assertEquals("Hello World!", lines[0])
|
assertEquals("Hello World!", lines[0])
|
||||||
assertEquals("This is a resource.", lines[1])
|
assertEquals("This is a resource.", lines[1])
|
||||||
|
|
||||||
val migration = fileOpener.openResourceFile("migrations/012.sql")
|
val migration = fileOpener.openResourceFile("migrations/012.sql")
|
||||||
lines = migration.readLines()
|
lines = migration.lines()
|
||||||
assertEquals("delete from Score", lines[0])
|
assertEquals("delete from Score", lines[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,8 +25,8 @@ import kotlin.test.*
|
|||||||
|
|
||||||
|
|
||||||
class CheckmarkRepositoryTest : BaseTest() {
|
class CheckmarkRepositoryTest : BaseTest() {
|
||||||
@Test
|
suspend fun testCRUD() {
|
||||||
fun testCRUD() {
|
val db = resolver.getDatabase()
|
||||||
val habitA = 10
|
val habitA = 10
|
||||||
var checkmarksA = listOf(Checkmark(LocalDate(2019, 1, 15), 100),
|
var checkmarksA = listOf(Checkmark(LocalDate(2019, 1, 15), 100),
|
||||||
Checkmark(LocalDate(2019, 1, 7), 500),
|
Checkmark(LocalDate(2019, 1, 7), 500),
|
||||||
|
|||||||
@@ -25,52 +25,43 @@ import org.isoron.platform.io.*
|
|||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
class HabitRepositoryTest() : BaseTest() {
|
class HabitRepositoryTest() : BaseTest() {
|
||||||
|
suspend fun testCRUD() {
|
||||||
|
val db = resolver.getDatabase()
|
||||||
|
val original0 = Habit(id = 0,
|
||||||
|
name = "Wake up early",
|
||||||
|
description = "Did you wake up before 6am?",
|
||||||
|
frequency = Frequency(1, 1),
|
||||||
|
color = PaletteColor(3),
|
||||||
|
isArchived = false,
|
||||||
|
position = 0,
|
||||||
|
unit = "",
|
||||||
|
target = 0.0,
|
||||||
|
type = HabitType.BOOLEAN_HABIT)
|
||||||
|
|
||||||
lateinit var repository: HabitRepository
|
val original1 = Habit(id = 1,
|
||||||
lateinit private var original0: Habit
|
name = "Exercise",
|
||||||
lateinit private var original1: Habit
|
description = "Did you exercise for at least 20 minutes?",
|
||||||
lateinit private var original2: Habit
|
frequency = Frequency(1, 2),
|
||||||
|
color = PaletteColor(4),
|
||||||
|
isArchived = false,
|
||||||
|
position = 1,
|
||||||
|
unit = "",
|
||||||
|
target = 0.0,
|
||||||
|
type = HabitType.BOOLEAN_HABIT)
|
||||||
|
|
||||||
@BeforeTest
|
val original2 = Habit(id = 2,
|
||||||
fun setUp() {
|
name = "Learn Japanese",
|
||||||
original0 = Habit(id = 0,
|
description = "Did you study Japanese today?",
|
||||||
name = "Wake up early",
|
frequency = Frequency(1, 1),
|
||||||
description = "Did you wake up before 6am?",
|
color = PaletteColor(3),
|
||||||
frequency = Frequency(1, 1),
|
isArchived = false,
|
||||||
color = PaletteColor(3),
|
position = 2,
|
||||||
isArchived = false,
|
unit = "",
|
||||||
position = 0,
|
target = 0.0,
|
||||||
unit = "",
|
type = HabitType.BOOLEAN_HABIT)
|
||||||
target = 0.0,
|
|
||||||
type = HabitType.BOOLEAN_HABIT)
|
|
||||||
|
|
||||||
original1 = Habit(id = 1,
|
val repository = HabitRepository(db)
|
||||||
name = "Exercise",
|
|
||||||
description = "Did you exercise for at least 20 minutes?",
|
|
||||||
frequency = Frequency(1, 2),
|
|
||||||
color = PaletteColor(4),
|
|
||||||
isArchived = false,
|
|
||||||
position = 1,
|
|
||||||
unit = "",
|
|
||||||
target = 0.0,
|
|
||||||
type = HabitType.BOOLEAN_HABIT)
|
|
||||||
|
|
||||||
original2 = Habit(id = 2,
|
|
||||||
name = "Learn Japanese",
|
|
||||||
description = "Did you study Japanese today?",
|
|
||||||
frequency = Frequency(1, 1),
|
|
||||||
color = PaletteColor(3),
|
|
||||||
isArchived = false,
|
|
||||||
position = 2,
|
|
||||||
unit = "",
|
|
||||||
target = 0.0,
|
|
||||||
type = HabitType.BOOLEAN_HABIT)
|
|
||||||
|
|
||||||
repository = HabitRepository(db)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testFindAll() {
|
|
||||||
var habits = repository.findAll()
|
var habits = repository.findAll()
|
||||||
assertEquals(0, repository.nextId())
|
assertEquals(0, repository.nextId())
|
||||||
assertEquals(0, habits.size)
|
assertEquals(0, habits.size)
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ import org.isoron.*
|
|||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
class PreferencesRepositoryTest : BaseTest() {
|
class PreferencesRepositoryTest : BaseTest() {
|
||||||
@Test
|
suspend fun testUsage() {
|
||||||
fun testUsage() {
|
val db = resolver.getDatabase()
|
||||||
val prefs = PreferencesRepository(db)
|
val prefs = PreferencesRepository(db)
|
||||||
|
|
||||||
assertEquals("default", prefs.getString("non_existing_key", "default"))
|
assertEquals("default", prefs.getString("non_existing_key", "default"))
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class JsPreparedStatement(val stmt: dynamic) : PreparedStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun finalize() {
|
override fun finalize() {
|
||||||
|
stmt.free()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getInt(index: Int): Int {
|
override fun getInt(index: Int): Int {
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
package org.isoron.platform.io
|
package org.isoron.platform.io
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import org.w3c.dom.events.*
|
import org.w3c.dom.events.*
|
||||||
import org.w3c.xhr.*
|
import org.w3c.xhr.*
|
||||||
|
import kotlin.js.*
|
||||||
|
|
||||||
class JsFileOpener : FileOpener {
|
class JsFileOpener : FileOpener {
|
||||||
override fun openUserFile(filename: String): UserFile {
|
override fun openUserFile(filename: String): UserFile {
|
||||||
@@ -34,21 +36,26 @@ class JsFileOpener : FileOpener {
|
|||||||
|
|
||||||
class JsUserFile(filename: String) : UserFile {
|
class JsUserFile(filename: String) : UserFile {
|
||||||
override fun delete() {
|
override fun delete() {
|
||||||
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exists(): Boolean {
|
override fun exists(): Boolean {
|
||||||
return false
|
TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class JsResourceFile(val filename: String) : ResourceFile {
|
class JsResourceFile(val filename: String) : ResourceFile {
|
||||||
override fun readLines(): List<String> {
|
override suspend fun lines(): List<String> {
|
||||||
val xhr = XMLHttpRequest()
|
return Promise<List<String>> { resolve, reject ->
|
||||||
xhr.open("GET", "/assets/$filename", false)
|
val xhr = XMLHttpRequest()
|
||||||
xhr.send()
|
xhr.open("GET", "/assets/$filename", true)
|
||||||
return xhr.responseText.lines()
|
xhr.onload = { resolve(xhr.responseText.lines()) }
|
||||||
|
xhr.onerror = { reject(Exception()) }
|
||||||
|
xhr.send()
|
||||||
|
}.await()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun copyTo(dest: UserFile) {
|
override fun copyTo(dest: UserFile) {
|
||||||
|
TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,18 @@ package org.isoron
|
|||||||
|
|
||||||
import org.isoron.platform.gui.*
|
import org.isoron.platform.gui.*
|
||||||
import org.isoron.platform.io.*
|
import org.isoron.platform.io.*
|
||||||
|
import org.isoron.uhabits.*
|
||||||
import org.w3c.dom.*
|
import org.w3c.dom.*
|
||||||
import kotlin.browser.*
|
import kotlin.browser.*
|
||||||
|
|
||||||
actual class DependencyResolver {
|
actual class DependencyResolver {
|
||||||
actual fun getFileOpener(): FileOpener = JsFileOpener()
|
actual fun getFileOpener(): FileOpener = JsFileOpener()
|
||||||
|
|
||||||
actual fun getDatabase(): Database {
|
actual suspend fun getDatabase(): Database {
|
||||||
val db = eval("new SQL.Database()")
|
val nativeDB = eval("new SQL.Database()")
|
||||||
return JsDatabase(db)
|
val db = JsDatabase(nativeDB)
|
||||||
|
db.migrateTo(LOOP_DATABASE_VERSION, getFileOpener(), StandardLog())
|
||||||
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun createCanvas(width: Int, height: Int): Canvas {
|
actual fun createCanvas(width: Int, height: Int): Canvas {
|
||||||
|
|||||||
42
core/src/jsTest/kotlin/org/isoron/JsAsyncTests.kt
Normal file
42
core/src/jsTest/kotlin/org/isoron/JsAsyncTests.kt
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2019 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.isoron.platform.io.*
|
||||||
|
import org.isoron.uhabits.models.*
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class JsAsyncTests {
|
||||||
|
@Test
|
||||||
|
fun testLines() = GlobalScope.promise { FilesTest().testLines() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDatabase() = GlobalScope.promise { DatabaseTest().testUsage() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCheckmarkRepository() = GlobalScope.promise { CheckmarkRepositoryTest().testCRUD() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testHabitRepository() = GlobalScope.promise { HabitRepositoryTest().testCRUD() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPreferencesRepository() = GlobalScope.promise { PreferencesRepositoryTest().testUsage() }
|
||||||
|
}
|
||||||
@@ -23,12 +23,12 @@ import java.io.*
|
|||||||
import java.nio.file.*
|
import java.nio.file.*
|
||||||
|
|
||||||
class JavaResourceFile(private val path: Path) : ResourceFile {
|
class JavaResourceFile(private val path: Path) : ResourceFile {
|
||||||
override fun copyTo(dest: UserFile) {
|
override suspend fun lines(): List<String> {
|
||||||
Files.copy(path, (dest as JavaUserFile).path)
|
return Files.readAllLines(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readLines(): List<String> {
|
override fun copyTo(dest: UserFile) {
|
||||||
return Files.readAllLines(path)
|
Files.copy(path, (dest as JavaUserFile).path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stream(): InputStream {
|
fun stream(): InputStream {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package org.isoron
|
package org.isoron
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import org.isoron.platform.gui.*
|
import org.isoron.platform.gui.*
|
||||||
import org.isoron.platform.io.*
|
import org.isoron.platform.io.*
|
||||||
import org.isoron.uhabits.*
|
import org.isoron.uhabits.*
|
||||||
@@ -34,7 +35,7 @@ actual class DependencyResolver actual constructor() {
|
|||||||
|
|
||||||
actual fun getFileOpener(): FileOpener = fileOpener
|
actual fun getFileOpener(): FileOpener = fileOpener
|
||||||
|
|
||||||
actual fun getDatabase(): Database {
|
actual suspend fun getDatabase(): Database {
|
||||||
val dbFile = fileOpener.openUserFile("test.sqlite3")
|
val dbFile = fileOpener.openUserFile("test.sqlite3")
|
||||||
if (dbFile.exists()) dbFile.delete()
|
if (dbFile.exists()) dbFile.delete()
|
||||||
val db = databaseOpener.open(dbFile)
|
val db = databaseOpener.open(dbFile)
|
||||||
|
|||||||
42
core/src/jvmTest/kotlin/org/isoron/JavaAsyncTests.kt
Normal file
42
core/src/jvmTest/kotlin/org/isoron/JavaAsyncTests.kt
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2019 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.isoron.platform.io.*
|
||||||
|
import org.isoron.uhabits.models.*
|
||||||
|
import org.junit.*
|
||||||
|
|
||||||
|
class JavaAsyncTests {
|
||||||
|
@Test
|
||||||
|
fun testLines() = runBlocking { FilesTest().testLines() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDatabase() = runBlocking { DatabaseTest().testUsage() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCheckmarkRepository() = runBlocking { CheckmarkRepositoryTest().testCRUD() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testHabitRepository() = runBlocking { HabitRepositoryTest().testCRUD() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPreferencesRepository() = runBlocking { PreferencesRepositoryTest().testUsage() }
|
||||||
|
}
|
||||||
5
web/package-lock.json
generated
5
web/package-lock.json
generated
@@ -3615,6 +3615,11 @@
|
|||||||
"kotlin": "1.3.21"
|
"kotlin": "1.3.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"kotlinx-coroutines-core": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/kotlinx-coroutines-core/-/kotlinx-coroutines-core-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-RnxF8HVQlMmLQcmJXSZQowR9WpsoeslY6ogqDovb/2HumkkaUBlJuR4eiXwX0DDnoAq8mGPvncl1lRAhK2+ovg=="
|
||||||
|
},
|
||||||
"lcid": {
|
"lcid": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"kotlin": "^1.3.21",
|
"kotlin": "^1.3.21",
|
||||||
"kotlin-test": "^1.3.21",
|
"kotlin-test": "^1.3.21",
|
||||||
|
"kotlinx-coroutines-core": "^1.1.1",
|
||||||
"sql.js": "^0.5.0"
|
"sql.js": "^0.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Reference in New Issue
Block a user