From fe4139e2686be4e87e35bbd8ad5452a81ff5da55 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Sat, 13 Apr 2019 22:28:05 -0500 Subject: [PATCH] Move tests to commonTest; convert some classes from Swift to Kotlin --- .../kotlin/org/isoron/DependencyResolver.kt | 8 ++ .../org/isoron/platform/gui/CanvasTest.kt | 1 + .../org/isoron/platform/io/DatabaseTest.kt | 1 + .../org/isoron/platform/time}/DatesTest.kt | 102 +++++++++--------- .../uhabits/models/CheckmarkRepositoryTest.kt | 1 + .../uhabits/models/HabitRepositoryTest.kt | 1 + .../models/PreferencesRepositoryTest.kt | 1 + .../org/isoron/platform/time/IosDates.kt | 55 ++++++++++ .../org/isoron/uhabits/IosLocaleHelper.kt | 67 ++++++++++++ .../kotlin/org/isoron/DependencyResolver.kt | 12 ++- .../org/isoron/platform/time/JsDates.kt | 27 +++-- .../kotlin/org/isoron/DependencyResolver.kt | 11 +- .../org/isoron/platform/time/JavaDates.kt | 7 -- .../kotlin/org/isoron/DependencyResolver.kt | 10 ++ ios/Application/AppDelegate.swift | 2 +- ios/Application/Platform/IosCanvas.swift | 13 +++ ios/Application/Platform/IosDates.swift | 60 ----------- ios/Application/Platform/IosLocale.swift | 64 ----------- ios/Tests/Platform/IosDatesTest.swift | 35 ------ ios/uhabits.xcodeproj/project.pbxproj | 16 --- 20 files changed, 247 insertions(+), 247 deletions(-) rename core/src/{jvmTest/kotlin/org/isoron/platform => commonTest/kotlin/org/isoron/platform/time}/DatesTest.kt (62%) create mode 100644 core/src/iosMain/kotlin/org/isoron/platform/time/IosDates.kt create mode 100644 core/src/iosMain/kotlin/org/isoron/uhabits/IosLocaleHelper.kt rename ios/Application/Platform/IosExtensions.swift => core/src/jsMain/kotlin/org/isoron/platform/time/JsDates.kt (58%) delete mode 100644 ios/Application/Platform/IosDates.swift delete mode 100644 ios/Application/Platform/IosLocale.swift delete mode 100644 ios/Tests/Platform/IosDatesTest.swift diff --git a/core/src/commonTest/kotlin/org/isoron/DependencyResolver.kt b/core/src/commonTest/kotlin/org/isoron/DependencyResolver.kt index 6fe0e97b9..2e30fddae 100644 --- a/core/src/commonTest/kotlin/org/isoron/DependencyResolver.kt +++ b/core/src/commonTest/kotlin/org/isoron/DependencyResolver.kt @@ -21,6 +21,11 @@ package org.isoron import org.isoron.platform.gui.* import org.isoron.platform.io.* +import org.isoron.platform.time.* + +enum class Locale { + US, JAPAN +} interface CanvasHelper { fun createCanvas(width: Int, height: Int): Canvas @@ -28,7 +33,10 @@ interface CanvasHelper { } expect object DependencyResolver { + val supportsDatabaseTests: Boolean + val supportsCanvasTests: Boolean suspend fun getFileOpener(): FileOpener suspend fun getDatabase(): Database fun getCanvasHelper(): CanvasHelper + fun getDateFormatter(locale: Locale): LocalDateFormatter } \ No newline at end of file diff --git a/core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt b/core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt index 0a54babe7..5d3b15223 100644 --- a/core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt @@ -25,6 +25,7 @@ import kotlin.test.* class CanvasTest { @Test fun run() { + if (!DependencyResolver.supportsCanvasTests) return val helper = DependencyResolver.getCanvasHelper() val canvas = helper.createCanvas(500, 400) diff --git a/core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt b/core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt index 533ab2489..dd5745549 100644 --- a/core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt @@ -26,6 +26,7 @@ class DatabaseTest { @Test fun testUsage() = asyncTest{ + if (!DependencyResolver.supportsDatabaseTests) return@asyncTest val db = DependencyResolver.getDatabase() db.setVersion(0) diff --git a/core/src/jvmTest/kotlin/org/isoron/platform/DatesTest.kt b/core/src/commonTest/kotlin/org/isoron/platform/time/DatesTest.kt similarity index 62% rename from core/src/jvmTest/kotlin/org/isoron/platform/DatesTest.kt rename to core/src/commonTest/kotlin/org/isoron/platform/time/DatesTest.kt index c8a9f52e4..cf64f50de 100644 --- a/core/src/jvmTest/kotlin/org/isoron/platform/DatesTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/platform/time/DatesTest.kt @@ -17,14 +17,10 @@ * with this program. If not, see . */ -package org.isoron.platform - -import junit.framework.TestCase.* -import org.isoron.platform.time.* -import org.junit.* -import java.util.* -import java.util.Calendar.* +package org.isoron.platform.time +import org.isoron.* +import kotlin.test.* class DatesTest { private val d1 = LocalDate(2019, 3, 25) @@ -32,7 +28,7 @@ class DatesTest { private val d3 = LocalDate(2019, 5, 12) @Test - fun plusMinusDays() { + fun testPlusMinusDays() { val today = LocalDate(2019, 3, 25) assertEquals(today.minus(28), LocalDate(2019, 2, 25)) assertEquals(today.plus(7), LocalDate(2019, 4, 1)) @@ -40,8 +36,8 @@ class DatesTest { } @Test - fun shortMonthName() { - var fmt = JavaLocalDateFormatter(Locale.US) + fun testFormatter() { + var fmt = DependencyResolver.getDateFormatter(Locale.US) assertEquals("Mon", fmt.shortWeekdayName(d1)) assertEquals("Thu", fmt.shortWeekdayName(d2)) assertEquals("Sun", fmt.shortWeekdayName(d3)) @@ -49,7 +45,7 @@ class DatesTest { assertEquals("Apr", fmt.shortMonthName(d2)) assertEquals("May", fmt.shortMonthName(d3)) - fmt = JavaLocalDateFormatter(Locale.JAPAN) + fmt = DependencyResolver.getDateFormatter(Locale.JAPAN) assertEquals("月", fmt.shortWeekdayName(d1)) assertEquals("木", fmt.shortWeekdayName(d2)) assertEquals("日", fmt.shortWeekdayName(d3)) @@ -59,13 +55,7 @@ class DatesTest { } @Test - fun weekDay() { - assertEquals(DayOfWeek.SUNDAY, LocalDate(2015, 1, 25).dayOfWeek) - assertEquals(DayOfWeek.MONDAY, LocalDate(2017, 7, 3).dayOfWeek) - } - - @Test - fun timestamps() { + fun testTimestamps() { val timestamps = listOf(Timestamp(1555977600000), Timestamp(968716800000), Timestamp(946684800000)) @@ -77,7 +67,7 @@ class DatesTest { } @Test - fun isOlderThan() { + fun testIsOlderThan() { val ref = LocalDate(2010, 10, 5) assertTrue(ref.isOlderThan(LocalDate(2010, 10, 10))) assertTrue(ref.isOlderThan(LocalDate(2010, 11, 4))) @@ -104,39 +94,49 @@ class DatesTest { } @Test - fun gregorianCalendarConversion() { - fun check(cal: GregorianCalendar, daysSince2000: Int) { - val year = cal.get(YEAR) - val month = cal.get(MONTH) + 1 - val day = cal.get(DAY_OF_MONTH) - val weekday = cal.get(DAY_OF_WEEK) - val date = LocalDate(year, month, day) - val millisSince1970 = cal.timeInMillis - val msg = "date=$year-$month-$day offset=$daysSince2000" - - assertEquals(msg, daysSince2000, date.daysSince2000) - assertEquals(msg, year, date.year) - assertEquals(msg, month, date.month) - assertEquals(msg, day, date.day) - assertEquals(msg, weekday, date.dayOfWeek.index + 1) - assertEquals(msg, millisSince1970, date.timestamp.millisSince1970) - assertEquals(msg, date, date.timestamp.localDate) + fun testGregorianCalendarConversion() { + fun check(daysSince2000: Int, + expectedYear: Int, + expectedMonth: Int, + expectedDay: Int, + expectedWeekday: Int) { + val date = LocalDate(daysSince2000) + assertEquals(expectedYear, date.year) + assertEquals(expectedMonth, date.month) + assertEquals(expectedDay, date.day) + assertEquals(expectedWeekday, date.dayOfWeek.index) + assertEquals(date, date.timestamp.localDate) } - val cal = GregorianCalendar() - cal.timeZone = TimeZone.getTimeZone("GMT") - cal.set(MILLISECOND, 0) - cal.set(SECOND, 0) - cal.set(MINUTE, 0) - cal.set(HOUR_OF_DAY, 0) - cal.set(DAY_OF_MONTH, 1) - cal.set(MONTH, 0) - cal.set(YEAR, 2000) - - // Check all dates from year 2000 until 2400 - for(offset in 0..146097) { - check(cal, offset) - cal.add(DAY_OF_YEAR, 1) - } + check(0, 2000, 1, 1, 6) + check(626, 2001, 9, 18, 2) + check(915, 2002, 7, 4, 4) + check(2759, 2007, 7, 22, 0) + check(2791, 2007, 8, 23, 4) + check(6524, 2017, 11, 11, 6) + check(7517, 2020, 7, 31, 5) + check(10031, 2027, 6, 19, 6) + check(13091, 2035, 11, 4, 0) + check(14849, 2040, 8, 27, 1) + check(17330, 2047, 6, 13, 4) + check(20566, 2056, 4, 22, 6) + check(23617, 2064, 8, 29, 5) + check(27743, 2075, 12, 16, 1) + check(31742, 2086, 11, 27, 3) + check(36659, 2100, 5, 15, 6) + check(39224, 2107, 5, 24, 2) + check(39896, 2109, 3, 26, 2) + check(40819, 2111, 10, 5, 1) + check(43983, 2120, 6, 3, 1) + check(46893, 2128, 5, 22, 6) + check(51013, 2139, 9, 2, 3) + check(55542, 2152, 1, 26, 3) + check(58817, 2161, 1, 13, 2) + check(63769, 2174, 8, 5, 5) + check(64893, 2177, 9, 2, 2) + check(66840, 2183, 1, 1, 3) + check(68011, 2186, 3, 17, 5) + check(70060, 2191, 10, 26, 3) + check(70733, 2193, 8, 29, 4) } } diff --git a/core/src/commonTest/kotlin/org/isoron/uhabits/models/CheckmarkRepositoryTest.kt b/core/src/commonTest/kotlin/org/isoron/uhabits/models/CheckmarkRepositoryTest.kt index cdc97b17e..af9c2c7c2 100644 --- a/core/src/commonTest/kotlin/org/isoron/uhabits/models/CheckmarkRepositoryTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/uhabits/models/CheckmarkRepositoryTest.kt @@ -28,6 +28,7 @@ import kotlin.test.* class CheckmarkRepositoryTest() { @Test fun testCRUD() = asyncTest { + if (!DependencyResolver.supportsDatabaseTests) return@asyncTest val db = DependencyResolver.getDatabase() val habitA = 10 diff --git a/core/src/commonTest/kotlin/org/isoron/uhabits/models/HabitRepositoryTest.kt b/core/src/commonTest/kotlin/org/isoron/uhabits/models/HabitRepositoryTest.kt index faa234d78..71a4582f3 100644 --- a/core/src/commonTest/kotlin/org/isoron/uhabits/models/HabitRepositoryTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/uhabits/models/HabitRepositoryTest.kt @@ -26,6 +26,7 @@ import kotlin.test.* class HabitRepositoryTest() { @Test fun testCRUD() = asyncTest{ + if (!DependencyResolver.supportsDatabaseTests) return@asyncTest val db = DependencyResolver.getDatabase() val original0 = Habit(id = 0, name = "Wake up early", diff --git a/core/src/commonTest/kotlin/org/isoron/uhabits/models/PreferencesRepositoryTest.kt b/core/src/commonTest/kotlin/org/isoron/uhabits/models/PreferencesRepositoryTest.kt index b24b65ecb..dde14ac44 100644 --- a/core/src/commonTest/kotlin/org/isoron/uhabits/models/PreferencesRepositoryTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/uhabits/models/PreferencesRepositoryTest.kt @@ -26,6 +26,7 @@ import kotlin.test.* class PreferencesRepositoryTest() { @Test fun testUsage() = asyncTest{ + if (!DependencyResolver.supportsDatabaseTests) return@asyncTest val db = DependencyResolver.getDatabase() val prefs = PreferencesRepository(db) assertEquals("default", prefs.getString("non_existing_key", "default")) diff --git a/core/src/iosMain/kotlin/org/isoron/platform/time/IosDates.kt b/core/src/iosMain/kotlin/org/isoron/platform/time/IosDates.kt new file mode 100644 index 000000000..424d6db92 --- /dev/null +++ b/core/src/iosMain/kotlin/org/isoron/platform/time/IosDates.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016-2019 Á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.time + +import platform.Foundation.* + +fun LocalDate.toNsDate(): NSDate { + val calendar = NSCalendar.calendarWithIdentifier(NSCalendarIdentifierGregorian)!! + val dc = NSDateComponents() + dc.year = year.toLong() + dc.month = month.toLong() + dc.day = day.toLong() + dc.hour = 13 + dc.minute = 0 + return calendar.dateFromComponents(dc)!! +} + +class IosLocalDateFormatter(val locale: String) : LocalDateFormatter { + + constructor() : this(NSLocale.preferredLanguages[0] as String) + + private val fmt = NSDateFormatter() + + init { + fmt.setLocale(NSLocale.localeWithLocaleIdentifier(locale)) + } + + override fun shortWeekdayName(date: LocalDate): String { + fmt.dateFormat = "EEE" + return fmt.stringFromDate(date.toNsDate()) + } + + override fun shortMonthName(date: LocalDate): String { + fmt.dateFormat = "MMM" + return fmt.stringFromDate(date.toNsDate()) + } + +} \ No newline at end of file diff --git a/core/src/iosMain/kotlin/org/isoron/uhabits/IosLocaleHelper.kt b/core/src/iosMain/kotlin/org/isoron/uhabits/IosLocaleHelper.kt new file mode 100644 index 000000000..985086cee --- /dev/null +++ b/core/src/iosMain/kotlin/org/isoron/uhabits/IosLocaleHelper.kt @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016-2019 Á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 . + */ + +@file:Suppress("UNCHECKED_CAST") + +package org.isoron.uhabits + +import org.isoron.platform.io.* +import org.isoron.uhabits.i18n.* +import platform.Foundation.* + +class IosLocaleHelper(private val log: Log) : LocaleHelper { + override fun getStringsForCurrentLocale(): Strings { + val pref = NSLocale.preferredLanguages as List + val lang = if (pref.isEmpty()) "en-US" else pref[0] + log.info("IosLocaleHelper", lang) + return when { + lang.startsWith("ar") -> StringsArabic() + lang.startsWith("ca") -> StringsCatalan() + lang.startsWith("cs") -> StringsCzech() + lang.startsWith("da") -> StringsDanish() + lang.startsWith("de") -> StringsGerman() + lang.startsWith("el") -> StringsGreek() + lang.startsWith("es") -> StringsSpanish() + lang.startsWith("fi") -> StringsFinnish() + lang.startsWith("fr") -> StringsFrench() + lang.startsWith("he") -> StringsHebrew() + lang.startsWith("hi") -> StringsHindi() + lang.startsWith("hr") -> StringsCroatian() + lang.startsWith("hu") -> StringsHungarian() + lang.startsWith("id") -> StringsIndonesian() + lang.startsWith("it") -> StringsItalian() + lang.startsWith("ja") -> StringsJapanese() + lang.startsWith("ko") -> StringsKorean() + lang.startsWith("nb") -> StringsNorwegian() + lang.startsWith("nl") -> StringsDutch() + lang.startsWith("pl") -> StringsPolish() + lang.startsWith("pt-BR") -> StringsPortugueseBR() + lang.startsWith("pt") -> StringsPortuguesePT() + lang.startsWith("ro") -> StringsRomanian() + lang.startsWith("ru") -> StringsRussian() + lang.startsWith("sk") -> StringsSlovak() + lang.startsWith("sv") -> StringsSwedish() + lang.startsWith("tr") -> StringsTurkish() + lang.startsWith("vi") -> StringsVietnamese() + lang.startsWith("zh-Hans") -> StringsChineseCN() + lang.startsWith("zh-Hant") -> StringsChineseTW() + else -> Strings() + } + } +} \ No newline at end of file diff --git a/core/src/iosTest/kotlin/org/isoron/DependencyResolver.kt b/core/src/iosTest/kotlin/org/isoron/DependencyResolver.kt index 36bedb4c7..ecd47752c 100644 --- a/core/src/iosTest/kotlin/org/isoron/DependencyResolver.kt +++ b/core/src/iosTest/kotlin/org/isoron/DependencyResolver.kt @@ -20,12 +20,22 @@ package org.isoron import org.isoron.platform.io.* +import org.isoron.platform.time.* actual object DependencyResolver { actual suspend fun getFileOpener(): FileOpener = IosFileOpener() + actual fun getDateFormatter(locale: Locale): LocalDateFormatter { + return when(locale) { + Locale.US -> IosLocalDateFormatter("en-US") + Locale.JAPAN -> IosLocalDateFormatter("ja-JP") + } + } + // IosDatabase and IosCanvas are currently implemented in Swift, so we - // cannot test these classes here. + // cannot test these classes here. The tests will be skipped. actual suspend fun getDatabase(): Database = TODO() actual fun getCanvasHelper(): CanvasHelper = TODO() + actual val supportsDatabaseTests = false + actual val supportsCanvasTests = false } \ No newline at end of file diff --git a/ios/Application/Platform/IosExtensions.swift b/core/src/jsMain/kotlin/org/isoron/platform/time/JsDates.kt similarity index 58% rename from ios/Application/Platform/IosExtensions.swift rename to core/src/jsMain/kotlin/org/isoron/platform/time/JsDates.kt index 7cafb31d1..0810d9df2 100644 --- a/ios/Application/Platform/IosExtensions.swift +++ b/core/src/jsMain/kotlin/org/isoron/platform/time/JsDates.kt @@ -17,17 +17,22 @@ * with this program. If not, see . */ -import UIKit +package org.isoron.platform.time -extension Color { - var uicolor: UIColor { - return UIColor(red: CGFloat(self.red), - green: CGFloat(self.green), - blue: CGFloat(self.blue), - alpha: CGFloat(self.alpha)) +import kotlin.js.* + +fun LocalDate.toJsDate(): Date { + return Date(year, month - 1, day) +} + +class JsDateFormatter(private val locale: String) : LocalDateFormatter { + override fun shortWeekdayName(date: LocalDate): String { + val options = dateLocaleOptions { weekday = "short" } + return date.toJsDate().toLocaleString(locale, options) } - - var cgcolor : CGColor { - return uicolor.cgColor + + override fun shortMonthName(date: LocalDate): String { + val options = dateLocaleOptions { month = "short" } + return date.toJsDate().toLocaleString(locale, options) } -} +} \ No newline at end of file diff --git a/core/src/jsTest/kotlin/org/isoron/DependencyResolver.kt b/core/src/jsTest/kotlin/org/isoron/DependencyResolver.kt index 4611a2e5f..423319080 100644 --- a/core/src/jsTest/kotlin/org/isoron/DependencyResolver.kt +++ b/core/src/jsTest/kotlin/org/isoron/DependencyResolver.kt @@ -21,12 +21,14 @@ package org.isoron import org.isoron.platform.gui.* import org.isoron.platform.io.* +import org.isoron.platform.time.* import org.isoron.uhabits.* import org.w3c.dom.* import kotlin.browser.* actual object DependencyResolver { - + actual val supportsDatabaseTests = true + actual val supportsCanvasTests = true var fileOpener: JsFileOpener? = null actual suspend fun getFileOpener(): FileOpener { @@ -48,6 +50,13 @@ actual object DependencyResolver { actual fun getCanvasHelper(): CanvasHelper { return JsCanvasHelper() } + + actual fun getDateFormatter(locale: Locale): LocalDateFormatter { + return when(locale) { + Locale.US -> JsDateFormatter("en-US") + Locale.JAPAN -> JsDateFormatter("ja-JP") + } + } } class JsCanvasHelper : CanvasHelper { diff --git a/core/src/jvmMain/kotlin/org/isoron/platform/time/JavaDates.kt b/core/src/jvmMain/kotlin/org/isoron/platform/time/JavaDates.kt index 72a385aa3..ebb0a0862 100644 --- a/core/src/jvmMain/kotlin/org/isoron/platform/time/JavaDates.kt +++ b/core/src/jvmMain/kotlin/org/isoron/platform/time/JavaDates.kt @@ -22,7 +22,6 @@ package org.isoron.platform.time import java.util.* import java.util.Calendar.* - fun LocalDate.toGregorianCalendar(): GregorianCalendar { val cal = GregorianCalendar() cal.timeZone = TimeZone.getTimeZone("GMT") @@ -36,12 +35,6 @@ fun LocalDate.toGregorianCalendar(): GregorianCalendar { return cal } -fun GregorianCalendar.toLocalDate(): LocalDate { - return LocalDate(this.get(YEAR), - this.get(MONTH) + 1, - this.get(DAY_OF_MONTH)) -} - class JavaLocalDateFormatter(private val locale: Locale) : LocalDateFormatter { override fun shortMonthName(date: LocalDate): String { val cal = date.toGregorianCalendar() diff --git a/core/src/jvmTest/kotlin/org/isoron/DependencyResolver.kt b/core/src/jvmTest/kotlin/org/isoron/DependencyResolver.kt index 22a393c18..ccb2d8688 100644 --- a/core/src/jvmTest/kotlin/org/isoron/DependencyResolver.kt +++ b/core/src/jvmTest/kotlin/org/isoron/DependencyResolver.kt @@ -21,12 +21,16 @@ package org.isoron import org.isoron.platform.gui.* import org.isoron.platform.io.* +import org.isoron.platform.time.* import org.isoron.uhabits.* import java.awt.image.* import java.io.* import javax.imageio.* actual object DependencyResolver { + actual val supportsDatabaseTests = true + actual val supportsCanvasTests = true + actual suspend fun getFileOpener(): FileOpener = JavaFileOpener() actual fun getCanvasHelper(): CanvasHelper = JavaCanvasHelper() @@ -42,6 +46,12 @@ actual object DependencyResolver { return db } + actual fun getDateFormatter(locale: Locale): LocalDateFormatter { + return when(locale) { + Locale.US -> JavaLocalDateFormatter(java.util.Locale.US) + Locale.JAPAN -> JavaLocalDateFormatter(java.util.Locale.JAPAN) + } + } } class JavaCanvasHelper : CanvasHelper { diff --git a/ios/Application/AppDelegate.swift b/ios/Application/AppDelegate.swift index 7aae707a8..d77771f14 100644 --- a/ios/Application/AppDelegate.swift +++ b/ios/Application/AppDelegate.swift @@ -32,7 +32,7 @@ import UIKit backend = Backend(databaseName: "uhabits.db", databaseOpener: IosDatabaseOpener(withLog: log), fileOpener: IosFileOpener(), - localeHelper: IosLocaleHelper(NSLocale.preferredLanguages), + localeHelper: IosLocaleHelper(log: log), log: log, scope: UIDispatcher()) diff --git a/ios/Application/Platform/IosCanvas.swift b/ios/Application/Platform/IosCanvas.swift index fd605918d..5a5d4a34c 100644 --- a/ios/Application/Platform/IosCanvas.swift +++ b/ios/Application/Platform/IosCanvas.swift @@ -19,6 +19,19 @@ import UIKit +extension Color { + var uicolor: UIColor { + return UIColor(red: CGFloat(self.red), + green: CGFloat(self.green), + blue: CGFloat(self.blue), + alpha: CGFloat(self.alpha)) + } + + var cgcolor : CGColor { + return uicolor.cgColor + } +} + class ComponentView : UIView { var component: Component? diff --git a/ios/Application/Platform/IosDates.swift b/ios/Application/Platform/IosDates.swift deleted file mode 100644 index 9230b2dfe..000000000 --- a/ios/Application/Platform/IosDates.swift +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2016-2019 Á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 . - */ - -import Foundation - -extension LocalDate { - var iosDate : Date { - let calendar = Calendar(identifier: .gregorian) - var dc = DateComponents() - dc.year = Int(self.year) - dc.month = Int(self.month) - dc.day = Int(self.day) - dc.hour = 13 - dc.minute = 0 - return calendar.date(from: dc)! - } -} - -extension Date { - var localDate : LocalDate { - let calendar = Calendar(identifier: .gregorian) - return LocalDate(year: Int32(calendar.component(.year, from: self)), - month: Int32(calendar.component(.month, from: self)), - day: Int32(calendar.component(.day, from: self))) - } -} - -class IosLocalDateFormatter : NSObject, LocalDateFormatter { - let fmt = DateFormatter() - - override init() { - fmt.locale = Locale(identifier: NSLocale.preferredLanguages.first!) - } - - func shortMonthName(date: LocalDate) -> String { - fmt.dateFormat = "MMM" - return fmt.string(from: date.iosDate) - } - - func shortWeekdayName(date: LocalDate) -> String { - fmt.dateFormat = "EEE" - return fmt.string(from: date.iosDate) - } -} diff --git a/ios/Application/Platform/IosLocale.swift b/ios/Application/Platform/IosLocale.swift deleted file mode 100644 index 2537d162d..000000000 --- a/ios/Application/Platform/IosLocale.swift +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2016-2019 Á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 . - */ - -import Foundation - -class IosLocaleHelper : NSObject, LocaleHelper { - var preferredLanguages: [String] - - init(_ preferredLanguages: [String]) { - self.preferredLanguages = preferredLanguages - } - - func getStringsForCurrentLocale() -> Strings { - let lang = preferredLanguages.first ?? "en-US" - StandardLog().debug(tag: "IosLocale", msg: lang) - if lang.hasPrefix("ar") { return StringsArabic() } - if lang.hasPrefix("fr") { return StringsFrench() } - if lang.hasPrefix("es") { return StringsSpanish() } - if lang.hasPrefix("pt-BR") { return StringsPortugueseBR() } - if lang.hasPrefix("pt") { return StringsPortuguesePT() } - if lang.hasPrefix("it") { return StringsItalian() } - if lang.hasPrefix("de") { return StringsGerman() } - if lang.hasPrefix("zh-Hans") { return StringsChineseCN() } - if lang.hasPrefix("zh-Hant") { return StringsChineseTW() } - if lang.hasPrefix("nl") { return StringsDutch() } - if lang.hasPrefix("ja") { return StringsJapanese() } - if lang.hasPrefix("ko") { return StringsKorean() } - if lang.hasPrefix("vi") { return StringsVietnamese() } - if lang.hasPrefix("ru") { return StringsRussian() } - if lang.hasPrefix("sv") { return StringsSwedish() } - if lang.hasPrefix("da") { return StringsDanish() } - if lang.hasPrefix("fi") { return StringsFinnish() } - if lang.hasPrefix("nb") { return StringsNorwegian() } - if lang.hasPrefix("tr") { return StringsTurkish() } - if lang.hasPrefix("el") { return StringsGreek() } - if lang.hasPrefix("id") { return StringsIndonesian() } - if lang.hasPrefix("hi") { return StringsHindi() } - if lang.hasPrefix("hu") { return StringsHungarian() } - if lang.hasPrefix("pl") { return StringsPolish() } - if lang.hasPrefix("cs") { return StringsCzech() } - if lang.hasPrefix("sk") { return StringsSlovak() } - if lang.hasPrefix("ca") { return StringsCatalan() } - if lang.hasPrefix("ro") { return StringsRomanian() } - if lang.hasPrefix("hr") { return StringsCroatian() } - if lang.hasPrefix("he") { return StringsHebrew() } - return Strings() - } -} diff --git a/ios/Tests/Platform/IosDatesTest.swift b/ios/Tests/Platform/IosDatesTest.swift deleted file mode 100644 index c3867439a..000000000 --- a/ios/Tests/Platform/IosDatesTest.swift +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2016-2019 Á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 . - */ - -import XCTest -import UIKit - -@testable import uhabits - -class IosDateFormatterTest : XCTestCase { - func testShortMonthName() { - let fmt = IosLocalDateFormatter() - let d1 = LocalDate(year: 2019, month: 3, day: 25) - let d2 = LocalDate(year: 2019, month: 4, day: 4) - let d3 = LocalDate(year: 2019, month: 5, day: 12) - XCTAssertEqual(fmt.shortWeekdayName(date: d1), "Mon") - XCTAssertEqual(fmt.shortWeekdayName(date: d2), "Thu") - XCTAssertEqual(fmt.shortWeekdayName(date: d3), "Sun") - } -} diff --git a/ios/uhabits.xcodeproj/project.pbxproj b/ios/uhabits.xcodeproj/project.pbxproj index 4855f75bf..cd9a13d9b 100644 --- a/ios/uhabits.xcodeproj/project.pbxproj +++ b/ios/uhabits.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 001592642260AE0F00D2814F /* main.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C0C6C92246E543003D8AF0 /* main.framework */; }; - 006EFE4E2252EA2B008464E0 /* IosLocale.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006EFE4D2252EA2B008464E0 /* IosLocale.swift */; }; 006EFE50225432B8008464E0 /* AboutScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006EFE4F225432B8008464E0 /* AboutScreenController.swift */; }; 00A5B42822009F590024E00C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A5B42722009F590024E00C /* AppDelegate.swift */; }; 00A5B42A22009F590024E00C /* MainScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A5B42922009F590024E00C /* MainScreenController.swift */; }; @@ -20,11 +19,8 @@ 00C0C6BF22465F65003D8AF0 /* migrations in Resources */ = {isa = PBXBuildFile; fileRef = 00C0C6BC22465F65003D8AF0 /* migrations */; }; 00C0C6CA2246E543003D8AF0 /* main.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C0C6C92246E543003D8AF0 /* main.framework */; }; 00C0C6CC2246E550003D8AF0 /* main.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 00C0C6C92246E543003D8AF0 /* main.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 00C0C6CE2246EFB3003D8AF0 /* IosExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6CD2246EFB3003D8AF0 /* IosExtensions.swift */; }; 00C0C6D122470705003D8AF0 /* IosCanvas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6D022470705003D8AF0 /* IosCanvas.swift */; }; 00C0C6D92247DC13003D8AF0 /* IosCanvasTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6D82247DC13003D8AF0 /* IosCanvasTest.swift */; }; - 00C0C6DB2247E6B0003D8AF0 /* IosDates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6DA2247E6B0003D8AF0 /* IosDates.swift */; }; - 00C0C6DD2247E6C4003D8AF0 /* IosDatesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6DC2247E6C4003D8AF0 /* IosDatesTest.swift */; }; 00C0C6E0224A3602003D8AF0 /* DetailScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6DE224A35FC003D8AF0 /* DetailScreenController.swift */; }; 00D48BD12200A31300CC4527 /* Launch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 00D48BD02200A31300CC4527 /* Launch.storyboard */; }; 00D48BD32200AC1600CC4527 /* EditHabitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D48BD22200AC1600CC4527 /* EditHabitController.swift */; }; @@ -55,7 +51,6 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 006EFE4D2252EA2B008464E0 /* IosLocale.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosLocale.swift; sourceTree = ""; }; 006EFE4F225432B8008464E0 /* AboutScreenController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutScreenController.swift; sourceTree = ""; }; 00A5B42422009F590024E00C /* uhabits.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = uhabits.app; sourceTree = BUILT_PRODUCTS_DIR; }; 00A5B42722009F590024E00C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -71,11 +66,8 @@ 00C0C6BB22465F65003D8AF0 /* databases */ = {isa = PBXFileReference; lastKnownFileType = folder; path = databases; sourceTree = ""; }; 00C0C6BC22465F65003D8AF0 /* migrations */ = {isa = PBXFileReference; lastKnownFileType = folder; path = migrations; sourceTree = ""; }; 00C0C6C92246E543003D8AF0 /* main.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = main.framework; path = ../core/build/bin/ios/mainDebugFramework/main.framework; sourceTree = ""; }; - 00C0C6CD2246EFB3003D8AF0 /* IosExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosExtensions.swift; sourceTree = ""; }; 00C0C6D022470705003D8AF0 /* IosCanvas.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosCanvas.swift; sourceTree = ""; }; 00C0C6D82247DC13003D8AF0 /* IosCanvasTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosCanvasTest.swift; sourceTree = ""; }; - 00C0C6DA2247E6B0003D8AF0 /* IosDates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosDates.swift; sourceTree = ""; }; - 00C0C6DC2247E6C4003D8AF0 /* IosDatesTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosDatesTest.swift; sourceTree = ""; }; 00C0C6DE224A35FC003D8AF0 /* DetailScreenController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailScreenController.swift; sourceTree = ""; }; 00D48BD02200A31300CC4527 /* Launch.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Launch.storyboard; sourceTree = ""; }; 00D48BD22200AC1600CC4527 /* EditHabitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditHabitController.swift; sourceTree = ""; }; @@ -179,9 +171,6 @@ children = ( 00C0C6D022470705003D8AF0 /* IosCanvas.swift */, 00C0C6A7224654A2003D8AF0 /* IosDatabase.swift */, - 00C0C6DA2247E6B0003D8AF0 /* IosDates.swift */, - 00C0C6CD2246EFB3003D8AF0 /* IosExtensions.swift */, - 006EFE4D2252EA2B008464E0 /* IosLocale.swift */, ); path = Platform; sourceTree = ""; @@ -191,7 +180,6 @@ children = ( 00C0C6D82247DC13003D8AF0 /* IosCanvasTest.swift */, 00C0C6A222465365003D8AF0 /* IosDatabaseTest.swift */, - 00C0C6DC2247E6C4003D8AF0 /* IosDatesTest.swift */, ); path = Platform; sourceTree = ""; @@ -323,11 +311,8 @@ buildActionMask = 2147483647; files = ( 00C0C6D122470705003D8AF0 /* IosCanvas.swift in Sources */, - 00C0C6CE2246EFB3003D8AF0 /* IosExtensions.swift in Sources */, 00C0C6E0224A3602003D8AF0 /* DetailScreenController.swift in Sources */, 00C0C6A8224654A2003D8AF0 /* IosDatabase.swift in Sources */, - 006EFE4E2252EA2B008464E0 /* IosLocale.swift in Sources */, - 00C0C6DB2247E6B0003D8AF0 /* IosDates.swift in Sources */, 00A5B42A22009F590024E00C /* MainScreenController.swift in Sources */, 00A5B42822009F590024E00C /* AppDelegate.swift in Sources */, 00D48BD32200AC1600CC4527 /* EditHabitController.swift in Sources */, @@ -339,7 +324,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 00C0C6DD2247E6C4003D8AF0 /* IosDatesTest.swift in Sources */, 00C0C6D92247DC13003D8AF0 /* IosCanvasTest.swift in Sources */, 00C0C6A62246537E003D8AF0 /* IosDatabaseTest.swift in Sources */, );