diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8e01d9c6..c108e4c1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -21,6 +21,8 @@ plugins { id("com.android.application") id("kotlin-android") + id("unitto.android.application.jacoco") + id("jacoco") id("unitto.android.hilt") } @@ -56,6 +58,7 @@ android { isMinifyEnabled = false isShrinkResources = false applicationIdSuffix = ".debug" + enableUnitTestCoverage = true } // Release with analytics and minified, not debuggable diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index d66799f7..a5651a5c 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -65,5 +65,15 @@ gradlePlugin { id = "unitto.room" implementationClass = "UnittoRoomPlugin" } + + register("unittoAndroidApplicationJacoco") { + id = "unitto.android.application.jacoco" + implementationClass = "UnittoAndroidApplicationJacocoPlugin" + } + + register("unittoAndroidLibraryJacocoPlugin") { + id = "unitto.android.library.jacoco" + implementationClass = "UnittoAndroidLibraryJacocoPlugin" + } } } diff --git a/build-logic/convention/src/main/java/UnittoAndroidApplicationJacocoPlugin.kt b/build-logic/convention/src/main/java/UnittoAndroidApplicationJacocoPlugin.kt new file mode 100644 index 00000000..8b6159fe --- /dev/null +++ b/build-logic/convention/src/main/java/UnittoAndroidApplicationJacocoPlugin.kt @@ -0,0 +1,37 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2023 Elshan Agaev + * + * This program 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. + * + * This program 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 com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.sadellie.unitto.configureJacoco +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType + +@Suppress("UNUSED") +class UnittoAndroidApplicationJacocoPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.gradle.jacoco") + apply("com.android.application") + } + val extension = extensions.getByType() + configureJacoco(extension) + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/java/UnittoAndroidLibraryJacocoPlugin.kt b/build-logic/convention/src/main/java/UnittoAndroidLibraryJacocoPlugin.kt new file mode 100644 index 00000000..26938e3f --- /dev/null +++ b/build-logic/convention/src/main/java/UnittoAndroidLibraryJacocoPlugin.kt @@ -0,0 +1,37 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2023 Elshan Agaev + * + * This program 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. + * + * This program 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 com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.sadellie.unitto.configureJacoco +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType + +@Suppress("UNUSED") +class UnittoAndroidLibraryJacocoPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.gradle.jacoco") + apply("com.android.library") + } + val extension = extensions.getByType() + configureJacoco(extension) + } + } +} \ No newline at end of file diff --git a/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt b/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt index a417f4c3..c51737d9 100644 --- a/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt +++ b/build-logic/convention/src/main/java/com/sadellie/unitto/ConfigureKotlinAndroid.kt @@ -39,6 +39,12 @@ internal fun Project.configureKotlinAndroid( minSdk = 21 } + buildTypes { + getByName("debug") { + enableUnitTestCoverage = true + } + } + flavorDimensions += "mainFlavorDimension" productFlavors { create("playStore") {} diff --git a/build-logic/convention/src/main/java/com/sadellie/unitto/Jacoco.kt b/build-logic/convention/src/main/java/com/sadellie/unitto/Jacoco.kt new file mode 100644 index 00000000..7ac69315 --- /dev/null +++ b/build-logic/convention/src/main/java/com/sadellie/unitto/Jacoco.kt @@ -0,0 +1,90 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2023 Elshan Agaev + * + * This program 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. + * + * This program 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 com.sadellie.unitto + +import com.android.build.api.variant.AndroidComponentsExtension +import org.gradle.api.Project +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension +import org.gradle.testing.jacoco.plugins.JacocoTaskExtension +import org.gradle.testing.jacoco.tasks.JacocoReport +import java.util.Locale + +private val coverageExclusions = listOf( + // Android + "**/R.class", + "**/R\$*.class", + "**/BuildConfig.*", + "**/Manifest*.*" +) + +private fun String.capitalize() = replaceFirstChar { + if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() +} + + +internal fun Project.configureJacoco( + androidComponentsExtension: AndroidComponentsExtension<*, *, *>, +) { + configure { + toolVersion = libs.findVersion("orgJacocoOrgJacocoCore").get().toString() + } + + val jacocoTestReport = tasks.create("jacocoTestReport") + + androidComponentsExtension.onVariants { variant -> + val testTaskName = "test${variant.name.capitalize()}UnitTest" + + val reportTask = tasks.register("jacoco${testTaskName.capitalize()}Report", JacocoReport::class) { + dependsOn(testTaskName) + + reports { + xml.required.set(true) + html.required.set(true) + + + } + + classDirectories.setFrom( + fileTree("$buildDir/tmp/kotlin-classes/${variant.name}") { + exclude(coverageExclusions) + } + ) + + sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin")) + executionData.setFrom(file("$buildDir/jacoco/$testTaskName.exec")) + } + + jacocoTestReport.dependsOn(reportTask) + } + + tasks.withType().configureEach { + configure { + // Required for JaCoCo + Robolectric + isIncludeNoLocationClasses = true + + // Required for JDK 11 with the above + // https://github.com/gradle/gradle/issues/5184#issuecomment-391982009 + excludes = listOf("jdk.internal.*") + } + } +} diff --git a/data/epoch/build.gradle.kts b/build-logic/convention/src/main/java/com/sadellie/unitto/ProjectExtensions.kt similarity index 70% rename from data/epoch/build.gradle.kts rename to build-logic/convention/src/main/java/com/sadellie/unitto/ProjectExtensions.kt index a342257c..e73f0d76 100644 --- a/data/epoch/build.gradle.kts +++ b/build-logic/convention/src/main/java/com/sadellie/unitto/ProjectExtensions.kt @@ -16,15 +16,12 @@ * along with this program. If not, see . */ -plugins { - id("unitto.library") - id("unitto.android.hilt") -} +package com.sadellie.unitto -android { - namespace = "com.sadellie.unitto.data.epoch" -} +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType -dependencies { - testImplementation(libs.junit.junit) -} +val Project.libs + get(): VersionCatalog = extensions.getByType().named("libs") diff --git a/core/base/build.gradle.kts b/core/base/build.gradle.kts index 1ee78dca..020b6be5 100644 --- a/core/base/build.gradle.kts +++ b/core/base/build.gradle.kts @@ -18,6 +18,7 @@ plugins { id("unitto.library") + id("unitto.android.library.jacoco") } android { @@ -44,9 +45,9 @@ android { buildConfig = true } - lint { - this.warning.add("MissingTranslation") - } + testOptions.unitTests.isIncludeAndroidResources = true + + lint.warning.add("MissingTranslation") } fun com.android.build.api.dsl.VariantDimension.storeLink(url: String) { @@ -56,3 +57,7 @@ fun com.android.build.api.dsl.VariantDimension.storeLink(url: String) { "\"${url}\"" ) } + +dependencies { + testImplementation(libs.junit.junit) +} diff --git a/core/base/src/main/java/com/sadellie/unitto/core/base/OutputFormat.kt b/core/base/src/main/java/com/sadellie/unitto/core/base/OutputFormat.kt index c3002585..a20fb0ca 100644 --- a/core/base/src/main/java/com/sadellie/unitto/core/base/OutputFormat.kt +++ b/core/base/src/main/java/com/sadellie/unitto/core/base/OutputFormat.kt @@ -19,7 +19,7 @@ package com.sadellie.unitto.core.base /** - * Output format here means whether or now use engineering notation + * Output format here means whether or not use engineering notation */ object OutputFormat { // Never use engineering notation diff --git a/core/base/src/test/java/com/sadellie/unitto/core/base/OutputFormatTest.kt b/core/base/src/test/java/com/sadellie/unitto/core/base/OutputFormatTest.kt new file mode 100644 index 00000000..15a23a2c --- /dev/null +++ b/core/base/src/test/java/com/sadellie/unitto/core/base/OutputFormatTest.kt @@ -0,0 +1,45 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2023 Elshan Agaev + * + * This program 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. + * + * This program 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 com.sadellie.unitto.core.base + +import org.junit.Assert +import org.junit.Test + +class OutputFormatTest { + + @Test + fun testExists() { + Assert.assertNotNull(OutputFormat) + } + + @Test + fun testOutputFormatPlain() { + Assert.assertEquals(0, OutputFormat.PLAIN) + } + + @Test + fun testOutputFormatAllowEngineering() { + Assert.assertEquals(1, OutputFormat.ALLOW_ENGINEERING) + } + + @Test + fun testOutputFormatForceEngineering() { + Assert.assertEquals(2, OutputFormat.FORCE_ENGINEERING) + } +} \ No newline at end of file diff --git a/core/base/src/test/java/com/sadellie/unitto/core/base/SeparatorTest.kt b/core/base/src/test/java/com/sadellie/unitto/core/base/SeparatorTest.kt new file mode 100644 index 00000000..eef1bfec --- /dev/null +++ b/core/base/src/test/java/com/sadellie/unitto/core/base/SeparatorTest.kt @@ -0,0 +1,45 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2023 Elshan Agaev + * + * This program 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. + * + * This program 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 com.sadellie.unitto.core.base + +import org.junit.Assert +import org.junit.Test + +class SeparatorTest { + + @Test + fun testExists() { + Assert.assertNotNull(Separator) + } + + @Test + fun testSeparatorSpace() { + Assert.assertEquals(0, Separator.SPACE) + } + + @Test + fun testSeparatorPeriod() { + Assert.assertEquals(1, Separator.PERIOD) + } + + @Test + fun testSeparatorComma() { + Assert.assertEquals(2, Separator.COMMA) + } +} \ No newline at end of file diff --git a/core/base/src/test/java/com/sadellie/unitto/core/base/TokenTest.kt b/core/base/src/test/java/com/sadellie/unitto/core/base/TokenTest.kt new file mode 100644 index 00000000..826cccb0 --- /dev/null +++ b/core/base/src/test/java/com/sadellie/unitto/core/base/TokenTest.kt @@ -0,0 +1,150 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2023 Elshan Agaev + * + * This program 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. + * + * This program 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 com.sadellie.unitto.core.base + +import org.junit.Assert +import org.junit.Test + +class TokenTest { + @Test + fun testDigit() { + Assert.assertEquals("1234567890", Token.Digit.all.joinToString("")) + Assert.assertEquals("1234567890.", Token.Digit.allWithDot.joinToString("")) + } + + @Test + fun testLetter() { + Assert.assertEquals("ABCDEF", Token.Letter.all.joinToString("")) + } + + @Test + fun testOperator() { + listOf( + "+", + "−", + "×", + "÷", + "(", + ")", + "^", + "!", + "#", + "%", + "√", + ).forEach { + assert(it in Token.Operator.all) + } + } + + @Test + fun testFunc() { + listOf( + "sin", + "cos", + "tan", + "sin⁻¹", + "cos⁻¹", + "tan⁻¹", + "ln", + "log", + "exp", + ).forEach { + assert(it in Token.Func.all) + } + + listOf( + "sin(", + "cos(", + "tan(", + "sin⁻¹(", + "cos⁻¹(", + "tan⁻¹(", + "ln(", + "log(", + "exp(", + ).forEach { + assert(it in Token.Func.allWithOpeningBracket) + } + } + + @Test + fun testConst() { + listOf( + "π", + "e", + ).forEach { + assert(it in Token.Const.all) + } + } + + @Test + fun testExpressionTokens() { + val operator = listOf( + "+", + "−", + "×", + "÷", + "(", + ")", + "^", + "!", + "#", + "%", + "√", + ).joinToString("") + + val func = listOf( + "sin⁻¹", + "cos⁻¹", + "tan⁻¹", + "sin", + "cos", + "tan", + "log", + "exp", + "ln", + ).joinToString("") + + val consts = listOf( + "π", + "e", + ).joinToString("") + + Assert.assertEquals("1234567890.$operator$func$consts", Token.expressionTokens.joinToString("")) + } + + @Test + fun testNumberBaseTokens() { + Assert.assertEquals("1234567890ABCDEF", Token.numberBaseTokens.joinToString("")) + } + + @Test + fun testDisplayOnlyObject() { + Assert.assertNotNull(Token.DisplayOnly) + } + + @Test + fun testSexyToUgly() { + listOf( + "−", "÷", "×", "sin⁻¹", "cos⁻¹", "tan⁻¹" + ).forEach { + assert(it in Token.sexyToUgly.keys) + } + } +} \ No newline at end of file diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index e126ca56..daaf14b3 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -22,23 +22,20 @@ plugins { id("unitto.library") id("unitto.library.compose") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { namespace = "com.sadellie.unitto.core.ui" // Workaround from https://github.com/robolectric/robolectric/pull/4736 - testOptions { - unitTests { - isIncludeAndroidResources = true - } - } + testOptions.unitTests.isIncludeAndroidResources = true } dependencies { testImplementation(libs.junit.junit) testImplementation(libs.org.robolectric.robolectric) - testImplementation(libs.androidx.compose.ui.test.junit4) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) debugImplementation(libs.androidx.compose.ui.test.manifest) implementation(libs.androidx.navigation.navigation.compose) diff --git a/core/ui/src/test/java/com/sadellie/unitto/core/ui/ZonedDateTimeUtilsTest.kt b/core/ui/src/androidTest/java/com/sadellie/unitto/core/ui/ZonedDateTimeUtilsTest.kt similarity index 81% rename from core/ui/src/test/java/com/sadellie/unitto/core/ui/ZonedDateTimeUtilsTest.kt rename to core/ui/src/androidTest/java/com/sadellie/unitto/core/ui/ZonedDateTimeUtilsTest.kt index 284ab64f..faefc4a3 100644 --- a/core/ui/src/test/java/com/sadellie/unitto/core/ui/ZonedDateTimeUtilsTest.kt +++ b/core/ui/src/androidTest/java/com/sadellie/unitto/core/ui/ZonedDateTimeUtilsTest.kt @@ -18,23 +18,21 @@ package com.sadellie.unitto.core.ui -import androidx.compose.ui.test.junit4.createComposeRule +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.createAndroidComposeRule import com.sadellie.unitto.core.ui.datetime.formatOffset +import org.junit.Assert.assertEquals import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.junit.Assert.assertEquals -import org.robolectric.RobolectricTestRunner import java.time.ZonedDateTime -@RunWith(RobolectricTestRunner::class) class ZonedDateTimeUtilsTest { @get: Rule - val composeTestRule = createComposeRule() + val composeTestRule = createAndroidComposeRule() @Test - fun `no difference`() = composeTestRule.setContent { + fun noDifference() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -45,7 +43,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show positive hour`() = composeTestRule.setContent { + fun showPositiveHour() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -58,7 +56,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show positive hour minute`() = composeTestRule.setContent { + fun showPositiveHourMinute() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -71,7 +69,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show positive hour minute day`() = composeTestRule.setContent { + fun showPositiveHourMinuteDay() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -84,7 +82,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show positive minute`() = composeTestRule.setContent { + fun showPositiveMinute() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -97,7 +95,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show positive minute day`() = composeTestRule.setContent { + fun showPositiveMinuteDay() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(23) .withMinute(45) @@ -110,7 +108,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show negative hour`() = composeTestRule.setContent { + fun showNegativeHour() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -123,7 +121,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show negative hour minute`() = composeTestRule.setContent { + fun showNegativeHourMinute() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -136,7 +134,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show negative hour minute day`() = composeTestRule.setContent { + fun showNegativeHourMinuteDay() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -149,7 +147,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show negative minute`() = composeTestRule.setContent { + fun showNegativeMinute() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(12) .withMinute(0) @@ -162,7 +160,7 @@ class ZonedDateTimeUtilsTest { } @Test - fun `show negative minute day`() = composeTestRule.setContent { + fun showNegativeMinuteDay() = composeTestRule.setContent { val currentTime = ZonedDateTime.now() .withHour(0) .withMinute(15) diff --git a/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt b/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt index d82866b1..c0dbe8bb 100644 --- a/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt +++ b/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt @@ -18,14 +18,10 @@ package com.sadellie.unitto.core.ui -import androidx.compose.ui.test.junit4.createComposeRule import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.core.ui.common.textfield.formatExpression import org.junit.Assert.assertEquals -import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner private const val ENG_VALUE = "123E+21" private const val ENG_VALUE_FRACTIONAL = "123.3E+21" @@ -37,12 +33,8 @@ private const val COMPLETE_EXPR = "50+123456÷8×0.8-12+0-√9×4^9+2×(9+8×7)" private const val LONG_HALF_COMPLETE_EXPR = "50+123456÷89078..9×0.8-12+0-√9×4^9+2×(9+8×7)×sin(13sin123cos" private const val SOME_BRACKETS = "((((((((" -@RunWith(RobolectricTestRunner::class) class FormatterTest { - @get: Rule - val composeTestRule = createComposeRule() - @Test fun setSeparatorSpaces() { fun String.format(): String = formatExpression(FormatterSymbols.Spaces) diff --git a/data/calculator/build.gradle.kts b/data/calculator/build.gradle.kts index e5919173..8cc8d086 100644 --- a/data/calculator/build.gradle.kts +++ b/data/calculator/build.gradle.kts @@ -19,6 +19,7 @@ plugins { id("unitto.library") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/data/common/build.gradle.kts b/data/common/build.gradle.kts index eda1e259..7d378bc3 100644 --- a/data/common/build.gradle.kts +++ b/data/common/build.gradle.kts @@ -18,6 +18,7 @@ plugins { id("unitto.library") + id("unitto.android.library.jacoco") } android { diff --git a/data/database/build.gradle.kts b/data/database/build.gradle.kts index 111a6b01..a10dd391 100644 --- a/data/database/build.gradle.kts +++ b/data/database/build.gradle.kts @@ -20,6 +20,7 @@ plugins { id("unitto.library") id("unitto.android.hilt") id("unitto.room") + id("unitto.android.library.jacoco") } android { diff --git a/data/epoch/.gitignore b/data/epoch/.gitignore deleted file mode 100644 index 42afabfd..00000000 --- a/data/epoch/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/data/epoch/consumer-rules.pro b/data/epoch/consumer-rules.pro deleted file mode 100644 index e69de29b..00000000 diff --git a/data/epoch/src/main/AndroidManifest.xml b/data/epoch/src/main/AndroidManifest.xml deleted file mode 100644 index 7bdbce91..00000000 --- a/data/epoch/src/main/AndroidManifest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/data/epoch/src/main/java/com/sadellie/unitto/data/epoch/EpochDateConverter.kt b/data/epoch/src/main/java/com/sadellie/unitto/data/epoch/EpochDateConverter.kt deleted file mode 100644 index d4957eb2..00000000 --- a/data/epoch/src/main/java/com/sadellie/unitto/data/epoch/EpochDateConverter.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Unitto is a unit converter for Android - * Copyright (c) 2023 Elshan Agaev - * - * This program 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. - * - * This program 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 com.sadellie.unitto.data.epoch - -import java.time.LocalDateTime -import java.time.ZoneOffset -import java.time.format.DateTimeFormatter -import java.time.format.DateTimeParseException - -object EpochDateConverter { - private val pattern by lazy { - DateTimeFormatter.ofPattern("HHmmssddMMyyyy") - } - - fun convertDateToUnix(date: String): String { - return try { - // Here we add some zeros, so that input is 14 symbols long - LocalDateTime - .parse(date.padEnd(14, '0'), pattern) - .toEpochSecond(ZoneOffset.UTC) - } catch (e: DateTimeParseException) { - 0 - }.toString() - } - - fun convertUnixToDate(unix: String): String { - val unixLong = unix.toLong().takeIf { it <= 253402300559L } - ?: throw IllegalArgumentException("Max unix is 253402300559") - - return LocalDateTime - .ofEpochSecond(unixLong, 0, ZoneOffset.UTC) - .format(pattern) - } -} \ No newline at end of file diff --git a/data/epoch/src/test/java/com/sadellie/unitto/data/epoch/DateToEpochTest.kt b/data/epoch/src/test/java/com/sadellie/unitto/data/epoch/DateToEpochTest.kt deleted file mode 100644 index 5a4ee4f7..00000000 --- a/data/epoch/src/test/java/com/sadellie/unitto/data/epoch/DateToEpochTest.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Unitto is a unit converter for Android - * Copyright (c) 2023 Elshan Agaev - * - * This program 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. - * - * This program 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 com.sadellie.unitto.data.epoch - -import org.junit.Assert.assertEquals -import org.junit.Test - -class DateToEpochTest { - - @Test - fun `00h0m00s 00 00 0000`() { - convertDateToUnixTest("00:00:00 00.00.0000", "0") - } - - @Test - fun `00h00m00s 01 01 0001`() { - convertDateToUnixTest("00:00:00 01.01.0001", "-62135596800") - } - - @Test - fun `00h00m00s 01 01 1970`() { - convertDateToUnixTest("00:00:00 01.01.1970", "0") - } - - @Test - fun `23h55m59s 31 12 9999`() { - convertDateToUnixTest("23:55:59 31.12.9999", "253402300559") - } - - @Test - fun `99h99m99s 99 99 9999`() { - convertDateToUnixTest("99:99:99 99.99.9999", "0") - } - - private fun convertDateToUnixTest(inputDate: String, expectedUnix: String) { - // Date input comes "fancy" - val cleanInputDate = inputDate.filter{ it.isDigit() } - assertEquals( - "Couldn't convert $inputDate ($cleanInputDate) into unix", - expectedUnix, - EpochDateConverter.convertDateToUnix(cleanInputDate) - ) - } -} diff --git a/data/epoch/src/test/java/com/sadellie/unitto/data/epoch/EpochToDateTest.kt b/data/epoch/src/test/java/com/sadellie/unitto/data/epoch/EpochToDateTest.kt deleted file mode 100644 index 12e16a68..00000000 --- a/data/epoch/src/test/java/com/sadellie/unitto/data/epoch/EpochToDateTest.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Unitto is a unit converter for Android - * Copyright (c) 2023 Elshan Agaev - * - * This program 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. - * - * This program 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 com.sadellie.unitto.data.epoch - -import org.junit.Assert.assertEquals -import org.junit.Assert.assertThrows -import org.junit.Test - -class EpochToDateTest { - - @Test - fun `0`() { - convertUnixToDate("0", "00:00:00 01.01.1970") - } - - @Test - fun `00000000000000 max input length`() { - convertUnixToDate("00000000000000", "00:00:00 01.01.1970") - } - - @Test - fun `253402300559 max possible date`() { - convertUnixToDate("253402300559", "23:55:59 31.12.9999") - } - - @Test - fun `2534023005599999 input longe than allowed`() { - convertUnixToDate("2534023005599999", "23:55:59 31.12.9999", IllegalArgumentException()) - } - - @Test - fun `99999999999999 max possible unix with max length`() { - convertUnixToDate("99999999999999", "23:55:59 31.12.9999", IllegalArgumentException()) - } - - private fun convertUnixToDate(inputUnix: String, expectedDate: String, throwable: Throwable? = null) { - // Date input comes "fancy" - val cleanExpectedDate = expectedDate.filter{ it.isDigit() } - - // Will throw - if (throwable != null) { - assertThrows( - "Failed to throw ${throwable.javaClass} when converting $inputUnix into $expectedDate ($cleanExpectedDate)", - throwable.javaClass - ) { EpochDateConverter.convertUnixToDate(inputUnix) } - return - } - - // Should actually convert - assertEquals( - "Couldn't convert $inputUnix into $expectedDate ($cleanExpectedDate)", - cleanExpectedDate, - EpochDateConverter.convertUnixToDate(inputUnix) - ) - } -} diff --git a/data/evaluatto/build.gradle.kts b/data/evaluatto/build.gradle.kts index ab006f96..e4ea4267 100644 --- a/data/evaluatto/build.gradle.kts +++ b/data/evaluatto/build.gradle.kts @@ -18,6 +18,7 @@ plugins { id("unitto.library") + id("unitto.android.library.jacoco") } android { diff --git a/data/evaluatto/src/test/java/io/github/sadellie/evaluatto/ExpressionExceptionsTest.kt b/data/evaluatto/src/test/java/io/github/sadellie/evaluatto/ExpressionExceptionsTest.kt index 262c5841..2a5fff6a 100644 --- a/data/evaluatto/src/test/java/io/github/sadellie/evaluatto/ExpressionExceptionsTest.kt +++ b/data/evaluatto/src/test/java/io/github/sadellie/evaluatto/ExpressionExceptionsTest.kt @@ -39,4 +39,7 @@ class ExpressionExceptionsTest { @Test fun `ugly ahh expression2`() = assertExprFail(TokenizerException.BadNumber::class.java, "...") + + @Test + fun `too big`() = assertExprFail(ExpressionException.TooBig::class.java, "999999!") } diff --git a/data/licenses/build.gradle.kts b/data/licenses/build.gradle.kts index 23709fac..c4703f00 100644 --- a/data/licenses/build.gradle.kts +++ b/data/licenses/build.gradle.kts @@ -19,6 +19,7 @@ plugins { id("unitto.library") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/data/model/build.gradle.kts b/data/model/build.gradle.kts index 7bc12002..43cbfa77 100644 --- a/data/model/build.gradle.kts +++ b/data/model/build.gradle.kts @@ -18,6 +18,7 @@ plugins { id("unitto.library") + id("unitto.android.library.jacoco") } android { diff --git a/data/timezone/build.gradle.kts b/data/timezone/build.gradle.kts index 4de5b10c..1e184ee4 100644 --- a/data/timezone/build.gradle.kts +++ b/data/timezone/build.gradle.kts @@ -19,6 +19,7 @@ plugins { id("unitto.library") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/data/units/build.gradle.kts b/data/units/build.gradle.kts index 65bd474d..757e87c4 100644 --- a/data/units/build.gradle.kts +++ b/data/units/build.gradle.kts @@ -20,6 +20,7 @@ plugins { id("unitto.library") id("unitto.android.hilt") id("unitto.room") + id("unitto.android.library.jacoco") } android { diff --git a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt index fac9163b..d60d1ce4 100644 --- a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt +++ b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt @@ -40,9 +40,11 @@ class AllUnitsTest { private var history: MutableMap> = mutableMapOf() private val mContext: Context = RuntimeEnvironment.getApplication().applicationContext + private val database = Room.inMemoryDatabaseBuilder(mContext, UnittoDatabase::class.java).build() private val allUnitsRepository = UnitsRepository( - Room.inMemoryDatabaseBuilder(mContext, UnittoDatabase::class.java).build().unitsDao(), - mContext + unitsDao = database.unitsDao(), + currencyRatesDao = database.currencyRatesDao(), + mContext = mContext ) @Test diff --git a/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt b/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt index f6acf9d8..e3a4a14f 100644 --- a/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt +++ b/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt @@ -38,7 +38,7 @@ val baseList = listOf( NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.kilometer, R.string.kilometer_short), NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.mile, R.string.mile_short), NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.pound, R.string.pound_short), - NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.kilometer_per_square_second, R.string.kilometer_per_square_second_short), + NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.kilometer_per_second, R.string.kilometer_per_second_short), ) @RunWith(RobolectricTestRunner::class) @@ -52,7 +52,7 @@ class LevenshteinFilterAndSortTest { val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList() println(result) assertEquals( - listOf("Kilometer", "Kilometer per square", "Attometer", "Nanometer"), + listOf("Kilometer", "Kilometer/second", "Attometer", "Nanometer"), result ) } @@ -63,7 +63,7 @@ class LevenshteinFilterAndSortTest { val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList() println(result) assertEquals( - listOf("Kilometer per square", "Kilometer"), + listOf("Kilometer", "Kilometer/second"), result ) } @@ -74,7 +74,7 @@ class LevenshteinFilterAndSortTest { val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList() println(result) assertEquals( - listOf("Meter", "Attometer", "Nanometer", "Millimeter", "Kilometer","Kilometer per square"), + listOf("Meter", "Attometer", "Nanometer", "Millimeter", "Kilometer","Kilometer/second"), result ) } @@ -96,7 +96,7 @@ class LevenshteinFilterAndSortTest { val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList() println(result) assertEquals( - listOf("Attometer", "Nanometer", "Millimeter", "Meter", "Kilometer", "Kilometer per square"), + listOf("Attometer", "Nanometer", "Millimeter", "Meter", "Kilometer", "Kilometer/second"), result ) } diff --git a/data/userprefs/build.gradle.kts b/data/userprefs/build.gradle.kts index 4c38ed40..c53b9775 100644 --- a/data/userprefs/build.gradle.kts +++ b/data/userprefs/build.gradle.kts @@ -19,6 +19,7 @@ plugins { id("unitto.library") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/feature/calculator/build.gradle.kts b/feature/calculator/build.gradle.kts index 905cabfd..507bbfc3 100644 --- a/feature/calculator/build.gradle.kts +++ b/feature/calculator/build.gradle.kts @@ -21,6 +21,7 @@ plugins { id("unitto.library.compose") id("unitto.library.feature") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/feature/converter/build.gradle.kts b/feature/converter/build.gradle.kts index 85849fd1..c62c521c 100644 --- a/feature/converter/build.gradle.kts +++ b/feature/converter/build.gradle.kts @@ -21,6 +21,7 @@ plugins { id("unitto.library.compose") id("unitto.library.feature") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/feature/datecalculator/build.gradle.kts b/feature/datecalculator/build.gradle.kts index 3a53ce37..3ccc44d3 100644 --- a/feature/datecalculator/build.gradle.kts +++ b/feature/datecalculator/build.gradle.kts @@ -21,6 +21,7 @@ plugins { id("unitto.library.compose") id("unitto.library.feature") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/feature/datecalculator/src/test/java/com/sadellie/unitto/feature/datecalculator/difference/ZonedDateTimeDifferenceKtTest.kt b/feature/datecalculator/src/test/java/com/sadellie/unitto/feature/datecalculator/difference/ZonedDateTimeDifferenceKtTest.kt index b67461e9..ad9fc7e6 100644 --- a/feature/datecalculator/src/test/java/com/sadellie/unitto/feature/datecalculator/difference/ZonedDateTimeDifferenceKtTest.kt +++ b/feature/datecalculator/src/test/java/com/sadellie/unitto/feature/datecalculator/difference/ZonedDateTimeDifferenceKtTest.kt @@ -24,10 +24,10 @@ import java.time.ZonedDateTime import java.time.format.DateTimeFormatter class ZonedDateTimeDifferenceKtTest { - private val fromatt: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") - private val `may 1 2023`: ZonedDateTime = ZonedDateTime.parse("2023-05-01 12:00", fromatt) - private val `may 2 2023`: ZonedDateTime = ZonedDateTime.parse("2023-05-02 12:00", fromatt) - private val `june 1 2023`: ZonedDateTime = ZonedDateTime.parse("2023-06-01 12:00", fromatt) + private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME + private val `may 1 2023`: ZonedDateTime = ZonedDateTime.parse("2023-05-01T12:00+01:00[Europe/Paris]", formatter) + private val `may 2 2023`: ZonedDateTime = ZonedDateTime.parse("2023-05-02T12:00+01:00[Europe/Paris]", formatter) + private val `june 1 2023`: ZonedDateTime = ZonedDateTime.parse("2023-06-01T12:00+01:00[Europe/Paris]", formatter) @Test fun `same dates`() { diff --git a/feature/settings/build.gradle.kts b/feature/settings/build.gradle.kts index 5e28fcd7..7624c35e 100644 --- a/feature/settings/build.gradle.kts +++ b/feature/settings/build.gradle.kts @@ -21,6 +21,7 @@ plugins { id("unitto.library.compose") id("unitto.library.feature") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/feature/timezone/build.gradle.kts b/feature/timezone/build.gradle.kts index a1603106..c8c3b176 100644 --- a/feature/timezone/build.gradle.kts +++ b/feature/timezone/build.gradle.kts @@ -21,6 +21,7 @@ plugins { id("unitto.library.compose") id("unitto.library.feature") id("unitto.android.hilt") + id("unitto.android.library.jacoco") } android { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 66b2a479..b35f30bf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,6 +22,7 @@ comGoogleAccompanistAccompanistSystemuicontroller = "0.30.1" comGoogleDagger = "2.47" comSquareupMoshiMoshiKotlin = "1.15.0" comSquareupRetrofit2ConverterMoshi = "2.9.0" +orgJacocoOrgJacocoCore = "0.8.10" junitJunit = "4.13.2" kotlin = "1.9.0" ksp = "1.9.0-1.0.13" @@ -68,10 +69,11 @@ android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", ver kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } com-google-dagger = { group = "com.google.dagger", name = "hilt-android-gradle-plugin", version.ref = "comGoogleDagger" } ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } +org-jacoco-org-jacoco-core = { group = "org.jacoco", name = "org.jacoco.core", version.ref = "orgJacocoOrgJacocoCore" } [plugins] android-gradlePlugin = { id = "com.android.application", version.ref = "androidGradlePlugin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "comGoogleDagger" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } -room = { id = "androidx.room", version.ref = "androidxRoom" } +room = { id = "androidx.room", version.ref = "androidxRoom" } \ No newline at end of file