From 3591fbc634bd6bba11baab6cc436c3441c492955 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Sun, 5 Mar 2023 02:01:54 +0400 Subject: [PATCH 01/12] Logo poll --- README.md | 8 ++++++++ where-logo.png | Bin 0 -> 75461 bytes 2 files changed, 8 insertions(+) create mode 100644 where-logo.png diff --git a/README.md b/README.md index 1fc01fe4..dbf9514c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ + +

+ +

+
+ +# Unitto – calculator and unit converter +

diff --git a/where-logo.png b/where-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dd1478b0ab3b7d56ec24aca2b3dc3416dfb80a2e GIT binary patch literal 75461 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 AbpQYW literal 0 HcmV?d00001 From dadf6f2a22217211bdb67d0dca5fd0b2704afc60 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Sun, 12 Mar 2023 20:07:57 +0300 Subject: [PATCH 02/12] Fix cursor position for grouping symbols (#27) Cursor is now correctly placed when grouping symbol appears/disappears --- .../feature/calculator/TextFieldController.kt | 31 +++++++++++++------ .../calculator/TextFieldControllerTest.kt | 7 +++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/TextFieldController.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/TextFieldController.kt index 63d38a88..cca32725 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/TextFieldController.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/TextFieldController.kt @@ -57,11 +57,15 @@ class TextFieldController @Inject constructor() { val inputFormatted = newInput.fixFormat() val newSelectionStartEnd = inputFormatted.length - lastToEndDistance + val fixedCursor = fixCursor( + newPosition = newSelectionStartEnd..newSelectionStartEnd, + currentInput = inputFormatted + ) ?: newSelectionStartEnd..newSelectionStartEnd input.update { it.copy( text = inputFormatted, - selection = TextRange(newSelectionStartEnd, newSelectionStartEnd) + selection = TextRange(fixedCursor) ) } } @@ -72,16 +76,9 @@ class TextFieldController @Inject constructor() { fun pasteSymbols(symbols: String) = addToInput(symbols.filterUnknownSymbols()) fun moveCursor(newPosition: IntRange) { - val currentInput = input.value.text - if (newPosition.last > currentInput.length) return - - val fixedLeftCursor = cursorFixer.fixCursorIfNeeded(currentInput, newPosition.first) - val fixedRightCursor = cursorFixer.fixCursorIfNeeded(currentInput, newPosition.last) - - // Will modify input.update { it.copy( - selection = TextRange(fixedLeftCursor, fixedRightCursor) + selection = TextRange(fixCursor(newPosition) ?: return) ) } } @@ -115,7 +112,7 @@ class TextFieldController @Inject constructor() { .fixFormat() it.copy( text = newText, - selection = TextRange(newText.length - distanceFromEnd) + selection = TextRange((newText.length - distanceFromEnd).coerceAtLeast(0)) ) } } @@ -126,10 +123,24 @@ class TextFieldController @Inject constructor() { .replace(localFormatter.grouping, "") .replace(localFormatter.fractional, Token.dot) + private fun fixCursor( + newPosition: IntRange, + currentInput: String = input.value.text + ): IntRange? { + if (newPosition.last > currentInput.length) return null + + val fixedLeftCursor = cursorFixer.fixCursorIfNeeded(currentInput, newPosition.first) + val fixedRightCursor = cursorFixer.fixCursorIfNeeded(currentInput, newPosition.last) + + return fixedLeftCursor..fixedRightCursor + } + private fun String.fixFormat(): String = localFormatter.reFormat(this) private fun String.filterUnknownSymbols() = localFormatter.filterUnknownSymbols(this) + private fun TextRange(range: IntRange): TextRange = TextRange(range.first, range.last) + inner class CursorFixer { private val illegalTokens by lazy { listOf( diff --git a/feature/calculator/src/test/java/com/sadellie/unitto/feature/calculator/TextFieldControllerTest.kt b/feature/calculator/src/test/java/com/sadellie/unitto/feature/calculator/TextFieldControllerTest.kt index e24a67c9..ee4d727c 100644 --- a/feature/calculator/src/test/java/com/sadellie/unitto/feature/calculator/TextFieldControllerTest.kt +++ b/feature/calculator/src/test/java/com/sadellie/unitto/feature/calculator/TextFieldControllerTest.kt @@ -184,6 +184,13 @@ internal class TextFieldControllerTest { textFieldController.delete() assertEquals("", textFieldController.text) assertEquals(0..0, textFieldController.selection) + + textFieldController.addToInput("1234") + // Place cursor like 1|,234 + textFieldController.moveCursor(1..1) + textFieldController.delete() + assertEquals("234", textFieldController.text) + assertEquals(0..0, textFieldController.selection) } @Test From 0ef363322e56ce965d8b792a0a425a056b4c2144 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Tue, 14 Mar 2023 13:01:25 +0300 Subject: [PATCH 03/12] Version 18 is released. --- app/build.gradle.kts | 2 +- fastlane/metadata/android/en-US/changelogs/18.txt | 1 + fastlane/metadata/android/ru/changelogs/18.txt | 1 + gradle/libs.versions.toml | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/18.txt create mode 100644 fastlane/metadata/android/ru/changelogs/18.txt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1fe6b8ed..4886f509 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -32,7 +32,7 @@ android { applicationId = "com.sadellie.unitto" minSdk = 21 targetSdk = 33 - versionCode = 17 + versionCode = 18 versionName = "Illuminating emerald" } diff --git a/fastlane/metadata/android/en-US/changelogs/18.txt b/fastlane/metadata/android/en-US/changelogs/18.txt new file mode 100644 index 00000000..cb278c5f --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/18.txt @@ -0,0 +1 @@ +Fixed crashes in calculator. \ No newline at end of file diff --git a/fastlane/metadata/android/ru/changelogs/18.txt b/fastlane/metadata/android/ru/changelogs/18.txt new file mode 100644 index 00000000..1630c196 --- /dev/null +++ b/fastlane/metadata/android/ru/changelogs/18.txt @@ -0,0 +1 @@ +Исправлены ошибки в калькуляторе. \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 289afa5c..c5c3287c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -appCode = "17" +appCode = "18" appName = "Illuminating emerald" kotlin = "1.8.10" androidxCore = "1.9.0" From 7eb0edaeedb0b98097a833b8914b16d013240f0b Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Tue, 21 Mar 2023 17:08:20 +0300 Subject: [PATCH 04/12] =?UTF-8?q?Fuck=20you,=20=F0=9F=A4=A1=20Huawei=20?= =?UTF-8?q?=F0=9F=A4=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - App will not receive any updates on Huawei AppGallery anymore --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dbf9514c..e71ded94 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ ## 📲 Download Google Play F-Droid -AppGallery +RuMarket ## 😎 Features - Instant expression evaluation From 5b8d811ad6625744d8e384d82e9fe6d181600780 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Wed, 22 Mar 2023 13:17:31 +0300 Subject: [PATCH 05/12] Added Electrostatic capacitance #28 --- core/base/src/main/res/values/strings.xml | 27 ++++++++++++ .../sadellie/unitto/data/model/UnitGroup.kt | 1 + .../unitto/data/units/AllUnitsRepository.kt | 2 + .../sadellie/unitto/data/units/MyUnitIDS.kt | 14 ++++++ .../data/units/collections/Capacitance.kt | 43 +++++++++++++++++++ .../unitto/data/units/AllUnitsTest.kt | 16 +++++++ 6 files changed, 103 insertions(+) create mode 100644 data/units/src/main/java/com/sadellie/unitto/data/units/collections/Capacitance.kt diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index 5de74fb9..8c452c10 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -971,6 +971,32 @@ Hexadecimal base16 + + Attofarad + aF + Statfarad + stF + Farad + F + Exafarad + EF + Picofarad + pF + Nanofarad + nF + Microfarad + µF + Millifarad + mF + Kilofarad + kF + Megafarad + MF + Gigafarad + GF + Petafarad + PF + Length Time @@ -989,6 +1015,7 @@ Currency Flux Base + Capacitance Convert from diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt index 22f8a7c8..22250ef7 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt @@ -48,4 +48,5 @@ enum class UnitGroup( DATA_TRANSFER(res = R.string.data_transfer), FLUX(res = R.string.flux), NUMBER_BASE(res = R.string.number_base), + ELECTROSTATIC_CAPACITANCE(res = R.string.electrostatic_capacitance) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt index 467b87a2..980ee487 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt @@ -41,6 +41,7 @@ import com.sadellie.unitto.data.units.collections.temperatureCollection import com.sadellie.unitto.data.units.collections.timeCollection import com.sadellie.unitto.data.units.collections.volumeCollection import com.sadellie.unitto.data.database.UnitsEntity +import com.sadellie.unitto.data.units.collections.electrostaticCapacitance import java.math.BigDecimal import javax.inject.Inject import javax.inject.Singleton @@ -79,6 +80,7 @@ class AllUnitsRepository @Inject constructor() { UnitGroup.DATA_TRANSFER to dataTransferCollection, UnitGroup.FLUX to fluxCollection, UnitGroup.NUMBER_BASE to numberBaseCollection, + UnitGroup.ELECTROSTATIC_CAPACITANCE to electrostaticCapacitance ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt index eb6669a8..ab64fac5 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt @@ -516,4 +516,18 @@ object MyUnitIDS { const val tetradecimal = "tetradecimal" const val pentadecimal = "pentadecimal" const val hexadecimal = "hexadecimal" + + // ELECTROSTATIC CAPACITANCE + const val attofarad = "attofarad" + const val statfarad = "statfarad" + const val farad = "farad" + const val exafarad = "exafarad" + const val picofarad = "picofarad" + const val nanofarad = "nanofarad" + const val microfarad = "microfarad" + const val millifarad = "millifarad" + const val kilofarad = "kilofarad" + const val megafarad = "megafarad" + const val gigafarad = "gigafarad" + const val petafarad = "petafarad" } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Capacitance.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Capacitance.kt new file mode 100644 index 00000000..63a997bf --- /dev/null +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Capacitance.kt @@ -0,0 +1,43 @@ +/* + * 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.units.collections + +import com.sadellie.unitto.data.model.AbstractUnit +import com.sadellie.unitto.data.model.MyUnit +import com.sadellie.unitto.data.model.UnitGroup +import com.sadellie.unitto.data.units.MyUnitIDS +import com.sadellie.unitto.data.units.R +import java.math.BigDecimal + +internal val electrostaticCapacitance: List by lazy { + listOf( + MyUnit(MyUnitIDS.attofarad, BigDecimal.valueOf(1), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.attofarad, R.string.attofarad_short), + MyUnit(MyUnitIDS.picofarad, BigDecimal.valueOf(1E+6), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.picofarad, R.string.picofarad_short), + MyUnit(MyUnitIDS.statfarad, BigDecimal.valueOf(1112650.0561), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.statfarad, R.string.statfarad_short), + MyUnit(MyUnitIDS.nanofarad, BigDecimal.valueOf(1E+9), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.nanofarad, R.string.nanofarad_short), + MyUnit(MyUnitIDS.microfarad, BigDecimal.valueOf(1E+12), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.microfarad, R.string.microfarad_short), + MyUnit(MyUnitIDS.millifarad, BigDecimal.valueOf(1E+15), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.millifarad, R.string.millifarad_short), + MyUnit(MyUnitIDS.farad, BigDecimal.valueOf(1E+18), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.farad, R.string.farad_short), + MyUnit(MyUnitIDS.kilofarad, BigDecimal.valueOf(1E+21), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.kilofarad, R.string.kilofarad_short), + MyUnit(MyUnitIDS.megafarad, BigDecimal.valueOf(1E+24), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.megafarad, R.string.megafarad_short), + MyUnit(MyUnitIDS.gigafarad, BigDecimal.valueOf(1E+27), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.gigafarad, R.string.gigafarad_short), + MyUnit(MyUnitIDS.petafarad, BigDecimal.valueOf(1E+33), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.petafarad, R.string.petafarad_short), + MyUnit(MyUnitIDS.exafarad, BigDecimal.valueOf(1E+36), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.exafarad, R.string.exafarad_short), + ) +} 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 57746019..df30c3c9 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 @@ -375,6 +375,22 @@ class AllUnitsTest { MyUnitIDS.hexadecimal.checkWith(MyUnitIDS.quinary, "FADE", "4023342") } + @Test + fun testElectrostaticCapacitance() { + MyUnitIDS.attofarad.checkWith(MyUnitIDS.nanofarad, "364354322342", "364.35432") + MyUnitIDS.statfarad.checkWith(MyUnitIDS.microfarad, "123312", "0.1372") + MyUnitIDS.farad.checkWith(MyUnitIDS.kilofarad, "123312", "123.312") + MyUnitIDS.exafarad.checkWith(MyUnitIDS.petafarad, "123312", "123312000") + MyUnitIDS.picofarad.checkWith(MyUnitIDS.nanofarad, "11233", "11.233") + MyUnitIDS.nanofarad.checkWith(MyUnitIDS.millifarad, "11233", "0.01123") + MyUnitIDS.microfarad.checkWith(MyUnitIDS.nanofarad, "1123433", "1123433000") + MyUnitIDS.millifarad.checkWith(MyUnitIDS.nanofarad, "112", "112000000") + MyUnitIDS.kilofarad.checkWith(MyUnitIDS.microfarad, "11132", "11132000000000") + MyUnitIDS.megafarad.checkWith(MyUnitIDS.kilofarad, "11132", "11132000") + MyUnitIDS.gigafarad.checkWith(MyUnitIDS.petafarad, "11132", "0.01113") + MyUnitIDS.petafarad.checkWith(MyUnitIDS.kilofarad, "11132", "11132000000000000") + } + private fun String.checkWith(checkingId: String, value: String, expected: String) { val unitFrom = allUnitsRepository.getById(this) val unitTo = allUnitsRepository.getById(checkingId) From c155f6c9c7b970e3bc32ea1c34262b678933b3be Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Wed, 22 Mar 2023 16:53:58 +0300 Subject: [PATCH 06/12] Added helper method for unit conversion test --- .../unitto/data/units/AllUnitsTest.kt | 610 +++++++++--------- 1 file changed, 306 insertions(+), 304 deletions(-) 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 df30c3c9..69d50051 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 @@ -35,360 +35,360 @@ class AllUnitsTest { private val allUnitsRepository = AllUnitsRepository() @Test - fun testAcceleration() { - MyUnitIDS.attometer_per_square_second.checkWith(MyUnitIDS.femtometer_per_square_second, "69", "0.069") - MyUnitIDS.femtometer_per_square_second.checkWith(MyUnitIDS.picometer_per_square_second, "69", "0.069") - MyUnitIDS.picometer_per_square_second.checkWith(MyUnitIDS.micrometer_per_square_second, "69", "0.00007") - MyUnitIDS.nanometer_per_square_second.checkWith(MyUnitIDS.centimeter_per_square_second, "69", "0.000007") - MyUnitIDS.micrometer_per_square_second.checkWith(MyUnitIDS.nanometer_per_square_second, "69", "69000") - MyUnitIDS.millimeter_per_square_second.checkWith(MyUnitIDS.centimeter_per_square_second, "69", "6.9") - MyUnitIDS.centimeter_per_square_second.checkWith(MyUnitIDS.meter_per_square_second, "69", "0.69") - MyUnitIDS.decimeter_per_square_second.checkWith(MyUnitIDS.meter_per_square_second, "69", "6.9") - MyUnitIDS.meter_per_square_second.checkWith(MyUnitIDS.micrometer_per_square_second, "69", "69000000") - MyUnitIDS.kilometer_per_square_second.checkWith(MyUnitIDS.hectometer_per_square_second, "69", "690") - MyUnitIDS.dekameter_per_square_second.checkWith(MyUnitIDS.gal, "69", "69000") - MyUnitIDS.hectometer_per_square_second.checkWith(MyUnitIDS.gal, "69", "690000") - MyUnitIDS.gal.checkWith(MyUnitIDS.centimeter_per_square_second, "69", "69") - MyUnitIDS.mercury_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "3.7") - MyUnitIDS.venus_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "8.87") - MyUnitIDS.earth_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "9.80655") - MyUnitIDS.mars_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "3.71") - MyUnitIDS.jupiter_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "24.79") - MyUnitIDS.saturn_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "10.44") - MyUnitIDS.uranus_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "8.87") - MyUnitIDS.neptune_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "11.15") - MyUnitIDS.sun_surface_gravity.checkWith(MyUnitIDS.meter_per_square_second, "1", "274") + fun testAcceleration() = testWithUnits { + attometer_per_square_second.checkWith(femtometer_per_square_second, "69", "0.069") + femtometer_per_square_second.checkWith(picometer_per_square_second, "69", "0.069") + picometer_per_square_second.checkWith(micrometer_per_square_second, "69", "0.00007") + nanometer_per_square_second.checkWith(centimeter_per_square_second, "69", "0.000007") + micrometer_per_square_second.checkWith(nanometer_per_square_second, "69", "69000") + millimeter_per_square_second.checkWith(centimeter_per_square_second, "69", "6.9") + centimeter_per_square_second.checkWith(meter_per_square_second, "69", "0.69") + decimeter_per_square_second.checkWith(meter_per_square_second, "69", "6.9") + meter_per_square_second.checkWith(micrometer_per_square_second, "69", "69000000") + kilometer_per_square_second.checkWith(hectometer_per_square_second, "69", "690") + dekameter_per_square_second.checkWith(gal, "69", "69000") + hectometer_per_square_second.checkWith(gal, "69", "690000") + gal.checkWith(centimeter_per_square_second, "69", "69") + mercury_surface_gravity.checkWith(meter_per_square_second, "1", "3.7") + venus_surface_gravity.checkWith(meter_per_square_second, "1", "8.87") + earth_surface_gravity.checkWith(meter_per_square_second, "1", "9.80655") + mars_surface_gravity.checkWith(meter_per_square_second, "1", "3.71") + jupiter_surface_gravity.checkWith(meter_per_square_second, "1", "24.79") + saturn_surface_gravity.checkWith(meter_per_square_second, "1", "10.44") + uranus_surface_gravity.checkWith(meter_per_square_second, "1", "8.87") + neptune_surface_gravity.checkWith(meter_per_square_second, "1", "11.15") + sun_surface_gravity.checkWith(meter_per_square_second, "1", "274") } @Test - fun testAngle() { - MyUnitIDS.angle_second.checkWith(MyUnitIDS.angle_minute, "420.5", "7.00833") - MyUnitIDS.angle_minute.checkWith(MyUnitIDS.radian, "420.5", "0.12232") - MyUnitIDS.degree.checkWith(MyUnitIDS.turn, "420.5", "1.16806") - MyUnitIDS.radian.checkWith(MyUnitIDS.turn, "420.5", "66.92465") - MyUnitIDS.sextant.checkWith(MyUnitIDS.radian, "420.5", "440.34657") - MyUnitIDS.turn.checkWith(MyUnitIDS.angle_minute, "420.5", "9082800") + fun testAngle() = testWithUnits { + angle_second.checkWith(angle_minute, "420.5", "7.00833") + angle_minute.checkWith(radian, "420.5", "0.12232") + degree.checkWith(turn, "420.5", "1.16806") + radian.checkWith(turn, "420.5", "66.92465") + sextant.checkWith(radian, "420.5", "440.34657") + turn.checkWith(angle_minute, "420.5", "9082800") } @Test - fun testArea() { - MyUnitIDS.cent.checkWith(MyUnitIDS.acre, "75.9", "7590") - MyUnitIDS.acre.checkWith(MyUnitIDS.square_kilometer, "75.9", "0.30716") - MyUnitIDS.hectare.checkWith(MyUnitIDS.square_foot, "75.9", "8169808.00585") - MyUnitIDS.square_foot.checkWith(MyUnitIDS.square_decimeter, "75.9", "705.13407") - MyUnitIDS.square_mile.checkWith(MyUnitIDS.square_foot, "75.9", "2115970560.8762") - MyUnitIDS.square_yard.checkWith(MyUnitIDS.square_foot, "75.9", "683.1") - MyUnitIDS.square_inch.checkWith(MyUnitIDS.square_foot, "75.9", "0.52708") - MyUnitIDS.square_micrometer.checkWith(MyUnitIDS.square_millimeter, "75.9", "0.00008") - MyUnitIDS.square_millimeter.checkWith(MyUnitIDS.square_centimeter, "75.9", "0.759") - MyUnitIDS.square_centimeter.checkWith(MyUnitIDS.acre, "75.9", "0.000002") - MyUnitIDS.square_decimeter.checkWith(MyUnitIDS.square_meter, "75.9", "0.759") - MyUnitIDS.square_meter.checkWith(MyUnitIDS.acre, "75.9", "0.01876") - MyUnitIDS.square_kilometer.checkWith(MyUnitIDS.hectare, "75.9", "7590") - MyUnitIDS.electron_cross_section.checkWith(MyUnitIDS.square_micrometer, "75.9", "0.000000000000005") + fun testArea() = testWithUnits { + cent.checkWith(acre, "75.9", "7590") + acre.checkWith(square_kilometer, "75.9", "0.30716") + hectare.checkWith(square_foot, "75.9", "8169808.00585") + square_foot.checkWith(square_decimeter, "75.9", "705.13407") + square_mile.checkWith(square_foot, "75.9", "2115970560.8762") + square_yard.checkWith(square_foot, "75.9", "683.1") + square_inch.checkWith(square_foot, "75.9", "0.52708") + square_micrometer.checkWith(square_millimeter, "75.9", "0.00008") + square_millimeter.checkWith(square_centimeter, "75.9", "0.759") + square_centimeter.checkWith(acre, "75.9", "0.000002") + square_decimeter.checkWith(square_meter, "75.9", "0.759") + square_meter.checkWith(acre, "75.9", "0.01876") + square_kilometer.checkWith(hectare, "75.9", "7590") + electron_cross_section.checkWith(square_micrometer, "75.9", "0.000000000000005") } @Test - fun testDataTransfer() { - MyUnitIDS.bit_per_second.checkWith(MyUnitIDS.kilobit_per_second, "2048", "2.048") - MyUnitIDS.kibibit_per_second.checkWith(MyUnitIDS.bit_per_second, "2048", "2097152") - MyUnitIDS.kilobit_per_second.checkWith(MyUnitIDS.bit_per_second, "2048", "2048000") - MyUnitIDS.megabit_per_second.checkWith(MyUnitIDS.kilobit_per_second, "2048", "2048000") - MyUnitIDS.mebibit_per_second.checkWith(MyUnitIDS.kilobit_per_second, "2048", "2147483.648") - MyUnitIDS.gigabit_per_second.checkWith(MyUnitIDS.kilobit_per_second, "2048", "2048000000") - MyUnitIDS.terabit_per_second.checkWith(MyUnitIDS.gigabyte_per_second, "2048", "256000") - MyUnitIDS.petabit_per_second.checkWith(MyUnitIDS.gigabyte_per_second, "2048", "256000000") - MyUnitIDS.exabit_per_second.checkWith(MyUnitIDS.petabit_per_second, "2048", "2048000") - MyUnitIDS.byte_per_second.checkWith(MyUnitIDS.bit_per_second, "2048", "16384") - MyUnitIDS.kibibyte_per_second.checkWith(MyUnitIDS.bit_per_second, "2048", "16777216") - MyUnitIDS.kilobyte_per_second.checkWith(MyUnitIDS.kibibit_per_second, "2048", "16000") - MyUnitIDS.megabyte_per_second.checkWith(MyUnitIDS.kilobyte_per_second, "2048", "2048000") - MyUnitIDS.mebibyte_per_second.checkWith(MyUnitIDS.bit_per_second, "2048", "17179869184") - MyUnitIDS.gigabyte_per_second.checkWith(MyUnitIDS.kilobyte_per_second, "2048", "2048000000") - MyUnitIDS.terabyte_per_second.checkWith(MyUnitIDS.gigabyte_per_second, "2048", "2048000") - MyUnitIDS.petabyte_per_second.checkWith(MyUnitIDS.terabyte_per_second, "2048", "2048000") - MyUnitIDS.exabyte_per_second.checkWith(MyUnitIDS.petabyte_per_second, "2048", "2048000") + fun testDataTransfer() = testWithUnits { + bit_per_second.checkWith(kilobit_per_second, "2048", "2.048") + kibibit_per_second.checkWith(bit_per_second, "2048", "2097152") + kilobit_per_second.checkWith(bit_per_second, "2048", "2048000") + megabit_per_second.checkWith(kilobit_per_second, "2048", "2048000") + mebibit_per_second.checkWith(kilobit_per_second, "2048", "2147483.648") + gigabit_per_second.checkWith(kilobit_per_second, "2048", "2048000000") + terabit_per_second.checkWith(gigabyte_per_second, "2048", "256000") + petabit_per_second.checkWith(gigabyte_per_second, "2048", "256000000") + exabit_per_second.checkWith(petabit_per_second, "2048", "2048000") + byte_per_second.checkWith(bit_per_second, "2048", "16384") + kibibyte_per_second.checkWith(bit_per_second, "2048", "16777216") + kilobyte_per_second.checkWith(kibibit_per_second, "2048", "16000") + megabyte_per_second.checkWith(kilobyte_per_second, "2048", "2048000") + mebibyte_per_second.checkWith(bit_per_second, "2048", "17179869184") + gigabyte_per_second.checkWith(kilobyte_per_second, "2048", "2048000000") + terabyte_per_second.checkWith(gigabyte_per_second, "2048", "2048000") + petabyte_per_second.checkWith(terabyte_per_second, "2048", "2048000") + exabyte_per_second.checkWith(petabyte_per_second, "2048", "2048000") } @Test - fun testEnergy() { - MyUnitIDS.electron_volt.checkWith(MyUnitIDS.joule, "56000000000000000000", "8.97219") - MyUnitIDS.attojoule.checkWith(MyUnitIDS.calorie_th, "41840000000000", "0.00001") - MyUnitIDS.joule.checkWith(MyUnitIDS.kilocalorie_th, "4184", "1") - MyUnitIDS.kilojoule.checkWith(MyUnitIDS.calorie_th, "4184000000", "1000000000000") - MyUnitIDS.megajoule.checkWith(MyUnitIDS.calorie_th, "0.4184", "100000") - MyUnitIDS.gigajoule.checkWith(MyUnitIDS.calorie_th, "0.4184", "100000000") - MyUnitIDS.energy_ton.checkWith(MyUnitIDS.calorie_th, "0.4184", "418400000") - MyUnitIDS.kiloton.checkWith(MyUnitIDS.calorie_th, "0.4184", "418400000000") - MyUnitIDS.megaton.checkWith(MyUnitIDS.calorie_th, "0.4184", "418400000000000") - MyUnitIDS.gigaton.checkWith(MyUnitIDS.calorie_th, "0.000000004184", "4184000000") - MyUnitIDS.energy_horse_power_metric.checkWith(MyUnitIDS.joule, "10", "26477955") - MyUnitIDS.calorie_th.checkWith(MyUnitIDS.joule, "10", "41.84") - MyUnitIDS.kilocalorie_th.checkWith(MyUnitIDS.joule, "10", "41840") + fun testEnergy() = testWithUnits { + electron_volt.checkWith(joule, "56000000000000000000", "8.97219") + attojoule.checkWith(calorie_th, "41840000000000", "0.00001") + joule.checkWith(kilocalorie_th, "4184", "1") + kilojoule.checkWith(calorie_th, "4184000000", "1000000000000") + megajoule.checkWith(calorie_th, "0.4184", "100000") + gigajoule.checkWith(calorie_th, "0.4184", "100000000") + energy_ton.checkWith(calorie_th, "0.4184", "418400000") + kiloton.checkWith(calorie_th, "0.4184", "418400000000") + megaton.checkWith(calorie_th, "0.4184", "418400000000000") + gigaton.checkWith(calorie_th, "0.000000004184", "4184000000") + energy_horse_power_metric.checkWith(joule, "10", "26477955") + calorie_th.checkWith(joule, "10", "41.84") + kilocalorie_th.checkWith(joule, "10", "41840") } @Test - fun testFileSize() { - MyUnitIDS.bit.checkWith(MyUnitIDS.kilobit, "2048", "2.048") - MyUnitIDS.kibibit.checkWith(MyUnitIDS.bit, "2048", "2097152") - MyUnitIDS.kilobit.checkWith(MyUnitIDS.bit, "2048", "2048000") - MyUnitIDS.megabit.checkWith(MyUnitIDS.kilobit, "2048", "2048000") - MyUnitIDS.mebibit.checkWith(MyUnitIDS.kilobit, "2048", "2147483.648") - MyUnitIDS.gigabit.checkWith(MyUnitIDS.kilobit, "2048", "2048000000") - MyUnitIDS.terabit.checkWith(MyUnitIDS.gigabyte, "2048", "256000") - MyUnitIDS.petabit.checkWith(MyUnitIDS.gigabyte, "2048", "256000000") - MyUnitIDS.exabit.checkWith(MyUnitIDS.petabit, "2048", "2048000") - MyUnitIDS.byte.checkWith(MyUnitIDS.bit, "2048", "16384") - MyUnitIDS.kibibyte.checkWith(MyUnitIDS.bit, "2048", "16777216") - MyUnitIDS.kilobyte.checkWith(MyUnitIDS.kibibit, "2048", "16000") - MyUnitIDS.megabyte.checkWith(MyUnitIDS.kilobyte, "2048", "2048000") - MyUnitIDS.mebibyte.checkWith(MyUnitIDS.bit, "2048", "17179869184") - MyUnitIDS.gigabyte.checkWith(MyUnitIDS.kilobyte, "2048", "2048000000") - MyUnitIDS.terabyte.checkWith(MyUnitIDS.gigabyte, "2048", "2048000") - MyUnitIDS.petabyte.checkWith(MyUnitIDS.terabyte, "2048", "2048000") - MyUnitIDS.exabyte.checkWith(MyUnitIDS.petabyte, "2048", "2048000") + fun testFileSize() = testWithUnits { + bit.checkWith(kilobit, "2048", "2.048") + kibibit.checkWith(bit, "2048", "2097152") + kilobit.checkWith(bit, "2048", "2048000") + megabit.checkWith(kilobit, "2048", "2048000") + mebibit.checkWith(kilobit, "2048", "2147483.648") + gigabit.checkWith(kilobit, "2048", "2048000000") + terabit.checkWith(gigabyte, "2048", "256000") + petabit.checkWith(gigabyte, "2048", "256000000") + exabit.checkWith(petabit, "2048", "2048000") + byte.checkWith(bit, "2048", "16384") + kibibyte.checkWith(bit, "2048", "16777216") + kilobyte.checkWith(kibibit, "2048", "16000") + megabyte.checkWith(kilobyte, "2048", "2048000") + mebibyte.checkWith(bit, "2048", "17179869184") + gigabyte.checkWith(kilobyte, "2048", "2048000000") + terabyte.checkWith(gigabyte, "2048", "2048000") + petabyte.checkWith(terabyte, "2048", "2048000") + exabyte.checkWith(petabyte, "2048", "2048000") } @Test - fun testLength() { - MyUnitIDS.attometer.checkWith(MyUnitIDS.micrometer, "158000000000.7", "0.158") - MyUnitIDS.nanometer.checkWith(MyUnitIDS.inch, "158000000000.7", "6220.47244") - MyUnitIDS.micrometer.checkWith(MyUnitIDS.inch, "158000000000.7", "6220472.44097") - MyUnitIDS.millimeter.checkWith(MyUnitIDS.inch, "158000.7", "6220.5") - MyUnitIDS.centimeter.checkWith(MyUnitIDS.inch, "158000.7", "62205") - MyUnitIDS.decimeter.checkWith(MyUnitIDS.foot, "158000.7", "51837.5") - MyUnitIDS.meter.checkWith(MyUnitIDS.yard, "158000.7", "172791.66667") - MyUnitIDS.kilometer.checkWith(MyUnitIDS.mile, "100", "62.13712") - MyUnitIDS.nautical_mile.checkWith(MyUnitIDS.kilometer, "100", "185.2") - MyUnitIDS.inch.checkWith(MyUnitIDS.foot, "100", "8.33333") - MyUnitIDS.foot.checkWith(MyUnitIDS.inch, "100", "1200") - MyUnitIDS.yard.checkWith(MyUnitIDS.foot, "100", "300") - MyUnitIDS.mile.checkWith(MyUnitIDS.foot, "100", "528000") - MyUnitIDS.light_year.checkWith(MyUnitIDS.foot, "0.0000001", "3103914196.85037") - MyUnitIDS.parsec.checkWith(MyUnitIDS.foot, "0.00000001", "1012361411.25044") - MyUnitIDS.kiloparsec.checkWith(MyUnitIDS.foot, "0.00000000001", "1012361411.25044") - MyUnitIDS.megaparsec.checkWith(MyUnitIDS.foot, "0.00000000000001", "1012361411.25044") - MyUnitIDS.mercury_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "2439.7") - MyUnitIDS.venus_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "6051.8") - MyUnitIDS.earth_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "6371") - MyUnitIDS.mars_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "3389.5") - MyUnitIDS.jupiter_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "69911") - MyUnitIDS.saturn_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "58232") - MyUnitIDS.uranus_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "25362") - MyUnitIDS.neptune_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "24622") - MyUnitIDS.sun_equatorial_radius.checkWith(MyUnitIDS.kilometer, "1", "695508") + fun testLength() = testWithUnits { + attometer.checkWith(micrometer, "158000000000.7", "0.158") + nanometer.checkWith(inch, "158000000000.7", "6220.47244") + micrometer.checkWith(inch, "158000000000.7", "6220472.44097") + millimeter.checkWith(inch, "158000.7", "6220.5") + centimeter.checkWith(inch, "158000.7", "62205") + decimeter.checkWith(foot, "158000.7", "51837.5") + meter.checkWith(yard, "158000.7", "172791.66667") + kilometer.checkWith(mile, "100", "62.13712") + nautical_mile.checkWith(kilometer, "100", "185.2") + inch.checkWith(foot, "100", "8.33333") + foot.checkWith(inch, "100", "1200") + yard.checkWith(foot, "100", "300") + mile.checkWith(foot, "100", "528000") + light_year.checkWith(foot, "0.0000001", "3103914196.85037") + parsec.checkWith(foot, "0.00000001", "1012361411.25044") + kiloparsec.checkWith(foot, "0.00000000001", "1012361411.25044") + megaparsec.checkWith(foot, "0.00000000000001", "1012361411.25044") + mercury_equatorial_radius.checkWith(kilometer, "1", "2439.7") + venus_equatorial_radius.checkWith(kilometer, "1", "6051.8") + earth_equatorial_radius.checkWith(kilometer, "1", "6371") + mars_equatorial_radius.checkWith(kilometer, "1", "3389.5") + jupiter_equatorial_radius.checkWith(kilometer, "1", "69911") + saturn_equatorial_radius.checkWith(kilometer, "1", "58232") + uranus_equatorial_radius.checkWith(kilometer, "1", "25362") + neptune_equatorial_radius.checkWith(kilometer, "1", "24622") + sun_equatorial_radius.checkWith(kilometer, "1", "695508") } @Test - fun testMass() { - MyUnitIDS.electron_mass_rest.checkWith(MyUnitIDS.milligram, "1500000000000000000", "0.000001") - MyUnitIDS.atomic_mass_unit.checkWith(MyUnitIDS.electron_mass_rest, "150", "273433.27951") - MyUnitIDS.milligram.checkWith(MyUnitIDS.ounce, "1500", "0.05291") - MyUnitIDS.gram.checkWith(MyUnitIDS.ounce, "1500", "52.91094") - MyUnitIDS.kilogram.checkWith(MyUnitIDS.carat, "1500", "7500000") - MyUnitIDS.metric_ton.checkWith(MyUnitIDS.carat, "1500", "7500000000") - MyUnitIDS.imperial_ton.checkWith(MyUnitIDS.kilogram, "1500", "1524070.3632") - MyUnitIDS.ounce.checkWith(MyUnitIDS.pound, "1500", "93.75") - MyUnitIDS.carat.checkWith(MyUnitIDS.pound, "1500", "0.66139") - MyUnitIDS.pound.checkWith(MyUnitIDS.kilogram, "1500", "680.38856") - MyUnitIDS.mercury_mass.checkWith(MyUnitIDS.kilogram, "1", "330104000000000000000000") - MyUnitIDS.venus_mass.checkWith(MyUnitIDS.kilogram, "1", "4867320000000000000000000") - MyUnitIDS.earth_mass.checkWith(MyUnitIDS.kilogram, "1", "5972190000000000000000000") - MyUnitIDS.mars_mass.checkWith(MyUnitIDS.kilogram, "1", "641693000000000000000000") - MyUnitIDS.jupiter_mass.checkWith(MyUnitIDS.kilogram, "1", "1898130000000000000000000000") - MyUnitIDS.saturn_mass.checkWith(MyUnitIDS.kilogram, "1", "568319000000000000000000000") - MyUnitIDS.uranus_mass.checkWith(MyUnitIDS.kilogram, "1", "86810300000000000000000000") - MyUnitIDS.neptune_mass.checkWith(MyUnitIDS.kilogram, "1", "102410000000000000000000000") - MyUnitIDS.sun_mass.checkWith(MyUnitIDS.kilogram, "1", "1989100000000000000000000000000") + fun testMass() = testWithUnits { + electron_mass_rest.checkWith(milligram, "1500000000000000000", "0.000001") + atomic_mass_unit.checkWith(electron_mass_rest, "150", "273433.27951") + milligram.checkWith(ounce, "1500", "0.05291") + gram.checkWith(ounce, "1500", "52.91094") + kilogram.checkWith(carat, "1500", "7500000") + metric_ton.checkWith(carat, "1500", "7500000000") + imperial_ton.checkWith(kilogram, "1500", "1524070.3632") + ounce.checkWith(pound, "1500", "93.75") + carat.checkWith(pound, "1500", "0.66139") + pound.checkWith(kilogram, "1500", "680.38856") + mercury_mass.checkWith(kilogram, "1", "330104000000000000000000") + venus_mass.checkWith(kilogram, "1", "4867320000000000000000000") + earth_mass.checkWith(kilogram, "1", "5972190000000000000000000") + mars_mass.checkWith(kilogram, "1", "641693000000000000000000") + jupiter_mass.checkWith(kilogram, "1", "1898130000000000000000000000") + saturn_mass.checkWith(kilogram, "1", "568319000000000000000000000") + uranus_mass.checkWith(kilogram, "1", "86810300000000000000000000") + neptune_mass.checkWith(kilogram, "1", "102410000000000000000000000") + sun_mass.checkWith(kilogram, "1", "1989100000000000000000000000000") } @Test - fun testPower() { - MyUnitIDS.attowatt.checkWith(MyUnitIDS.watt, "3950000000000000", "0.00395") - MyUnitIDS.watt.checkWith(MyUnitIDS.kilowatt, "395", "0.395") - MyUnitIDS.kilowatt.checkWith(MyUnitIDS.horse_power_mechanical, "395", "529.70373") - MyUnitIDS.megawatt.checkWith(MyUnitIDS.horse_power_mechanical, "395", "529703.72539") - MyUnitIDS.horse_power_mechanical.checkWith(MyUnitIDS.kilowatt, "395", "294.55145") + fun testPower() = testWithUnits { + attowatt.checkWith(watt, "3950000000000000", "0.00395") + watt.checkWith(kilowatt, "395", "0.395") + kilowatt.checkWith(horse_power_mechanical, "395", "529.70373") + megawatt.checkWith(horse_power_mechanical, "395", "529703.72539") + horse_power_mechanical.checkWith(kilowatt, "395", "294.55145") } @Test - fun testPressure() { - MyUnitIDS.attopascal.checkWith(MyUnitIDS.femtopascal, "456", "0.456") - MyUnitIDS.femtopascal.checkWith(MyUnitIDS.picopascal, "456", "0.456") - MyUnitIDS.picopascal.checkWith(MyUnitIDS.nanopascal, "456", "0.456") - MyUnitIDS.nanopascal.checkWith(MyUnitIDS.micropascal, "456", "0.456") - MyUnitIDS.micropascal.checkWith(MyUnitIDS.millipascal, "456", "0.456") - MyUnitIDS.millipascal.checkWith(MyUnitIDS.centipascal, "456", "45.6") - MyUnitIDS.centipascal.checkWith(MyUnitIDS.decipascal, "456", "45.6") - MyUnitIDS.decipascal.checkWith(MyUnitIDS.dekapascal, "456", "4.56") - MyUnitIDS.pascal.checkWith(MyUnitIDS.bar, "456", "0.00456") - MyUnitIDS.dekapascal.checkWith(MyUnitIDS.bar, "456", "0.0456") - MyUnitIDS.hectopascal.checkWith(MyUnitIDS.psi, "456", "6.61372") - MyUnitIDS.millibar.checkWith(MyUnitIDS.psi, "456", "6.61372") - MyUnitIDS.bar.checkWith(MyUnitIDS.ksi, "456", "6.61372") - MyUnitIDS.kilopascal.checkWith(MyUnitIDS.psi, "456", "66.13721") - MyUnitIDS.megapascal.checkWith(MyUnitIDS.ksi, "456", "66.13721") - MyUnitIDS.gigapascal.checkWith(MyUnitIDS.torr, "456", "3420281273.13024") - MyUnitIDS.terapascal.checkWith(MyUnitIDS.gigapascal, "456", "456000") - MyUnitIDS.petapascal.checkWith(MyUnitIDS.gigapascal, "456", "456000000") - MyUnitIDS.exapascal.checkWith(MyUnitIDS.gigapascal, "456", "456000000000") - MyUnitIDS.psi.checkWith(MyUnitIDS.gigapascal, "456", "0.00314") - MyUnitIDS.ksi.checkWith(MyUnitIDS.gigapascal, "456", "3.14401") - MyUnitIDS.standard_atmosphere.checkWith(MyUnitIDS.torr, "456", "346560") - MyUnitIDS.torr.checkWith(MyUnitIDS.hectopascal, "456", "607.95") - MyUnitIDS.micron_of_mercury.checkWith(MyUnitIDS.hectopascal, "456", "0.60795") - MyUnitIDS.millimeter_of_mercury.checkWith(MyUnitIDS.hectopascal, "456", "607.95") + fun testPressure() = testWithUnits { + attopascal.checkWith(femtopascal, "456", "0.456") + femtopascal.checkWith(picopascal, "456", "0.456") + picopascal.checkWith(nanopascal, "456", "0.456") + nanopascal.checkWith(micropascal, "456", "0.456") + micropascal.checkWith(millipascal, "456", "0.456") + millipascal.checkWith(centipascal, "456", "45.6") + centipascal.checkWith(decipascal, "456", "45.6") + decipascal.checkWith(dekapascal, "456", "4.56") + pascal.checkWith(bar, "456", "0.00456") + dekapascal.checkWith(bar, "456", "0.0456") + hectopascal.checkWith(psi, "456", "6.61372") + millibar.checkWith(psi, "456", "6.61372") + bar.checkWith(ksi, "456", "6.61372") + kilopascal.checkWith(psi, "456", "66.13721") + megapascal.checkWith(ksi, "456", "66.13721") + gigapascal.checkWith(torr, "456", "3420281273.13024") + terapascal.checkWith(gigapascal, "456", "456000") + petapascal.checkWith(gigapascal, "456", "456000000") + exapascal.checkWith(gigapascal, "456", "456000000000") + psi.checkWith(gigapascal, "456", "0.00314") + ksi.checkWith(gigapascal, "456", "3.14401") + standard_atmosphere.checkWith(torr, "456", "346560") + torr.checkWith(hectopascal, "456", "607.95") + micron_of_mercury.checkWith(hectopascal, "456", "0.60795") + millimeter_of_mercury.checkWith(hectopascal, "456", "607.95") } @Test - fun testSpeed() { - MyUnitIDS.millimeter_per_hour.checkWith(MyUnitIDS.kilometer_per_hour, "396", "0.0004") - MyUnitIDS.millimeter_per_minute.checkWith(MyUnitIDS.kilometer_per_hour, "396", "0.02376") - MyUnitIDS.millimeter_per_second.checkWith(MyUnitIDS.kilometer_per_hour, "396", "1.4256") - MyUnitIDS.centimeter_per_hour.checkWith(MyUnitIDS.kilometer_per_hour, "396", "0.00396") - MyUnitIDS.centimeter_per_minute.checkWith(MyUnitIDS.kilometer_per_hour, "396", "0.2376") - MyUnitIDS.centimeter_per_second.checkWith(MyUnitIDS.kilometer_per_hour, "396", "14.256") - MyUnitIDS.meter_per_hour.checkWith(MyUnitIDS.kilometer_per_hour, "396", "0.396") - MyUnitIDS.meter_per_minute.checkWith(MyUnitIDS.kilometer_per_hour, "396", "23.76") - MyUnitIDS.meter_per_second.checkWith(MyUnitIDS.kilometer_per_hour, "396", "1425.6") - MyUnitIDS.kilometer_per_hour.checkWith(MyUnitIDS.mile_per_hour, "396", "246.06299") - MyUnitIDS.kilometer_per_minute.checkWith(MyUnitIDS.mile_per_hour, "396", "14763.77953") - MyUnitIDS.kilometer_per_second.checkWith(MyUnitIDS.mile_per_hour, "396", "885826.77165") - MyUnitIDS.foot_per_hour.checkWith(MyUnitIDS.mile_per_hour, "396", "0.075") - MyUnitIDS.foot_per_minute.checkWith(MyUnitIDS.mile_per_hour, "396", "4.5") - MyUnitIDS.foot_per_second.checkWith(MyUnitIDS.mile_per_hour, "396", "270") - MyUnitIDS.yard_per_hour.checkWith(MyUnitIDS.mile_per_hour, "396", "0.225") - MyUnitIDS.yard_per_minute.checkWith(MyUnitIDS.mile_per_hour, "396", "13.5") - MyUnitIDS.yard_per_second.checkWith(MyUnitIDS.mile_per_hour, "396", "810") - MyUnitIDS.mile_per_hour.checkWith(MyUnitIDS.foot_per_hour, "396", "2090880") - MyUnitIDS.mile_per_minute.checkWith(MyUnitIDS.foot_per_hour, "396", "125452800") - MyUnitIDS.mile_per_second.checkWith(MyUnitIDS.foot_per_hour, "396", "7527168000") - MyUnitIDS.knot.checkWith(MyUnitIDS.meter_per_hour, "396", "733392") - MyUnitIDS.velocity_of_light_in_vacuum.checkWith(MyUnitIDS.meter_per_second, "1", "299792458") - MyUnitIDS.cosmic_velocity_first.checkWith(MyUnitIDS.meter_per_second, "1", "7900") - MyUnitIDS.cosmic_velocity_second.checkWith(MyUnitIDS.meter_per_second, "1", "11200") - MyUnitIDS.cosmic_velocity_third.checkWith(MyUnitIDS.meter_per_second, "1", "16670") - MyUnitIDS.earths_orbital_speed.checkWith(MyUnitIDS.meter_per_second, "1", "29765") - MyUnitIDS.mach.checkWith(MyUnitIDS.meter_per_second, "1", "343.6") - MyUnitIDS.mach_si_standard.checkWith(MyUnitIDS.meter_per_second, "1", "295.0464") + fun testSpeed() = testWithUnits { + millimeter_per_hour.checkWith(kilometer_per_hour, "396", "0.0004") + millimeter_per_minute.checkWith(kilometer_per_hour, "396", "0.02376") + millimeter_per_second.checkWith(kilometer_per_hour, "396", "1.4256") + centimeter_per_hour.checkWith(kilometer_per_hour, "396", "0.00396") + centimeter_per_minute.checkWith(kilometer_per_hour, "396", "0.2376") + centimeter_per_second.checkWith(kilometer_per_hour, "396", "14.256") + meter_per_hour.checkWith(kilometer_per_hour, "396", "0.396") + meter_per_minute.checkWith(kilometer_per_hour, "396", "23.76") + meter_per_second.checkWith(kilometer_per_hour, "396", "1425.6") + kilometer_per_hour.checkWith(mile_per_hour, "396", "246.06299") + kilometer_per_minute.checkWith(mile_per_hour, "396", "14763.77953") + kilometer_per_second.checkWith(mile_per_hour, "396", "885826.77165") + foot_per_hour.checkWith(mile_per_hour, "396", "0.075") + foot_per_minute.checkWith(mile_per_hour, "396", "4.5") + foot_per_second.checkWith(mile_per_hour, "396", "270") + yard_per_hour.checkWith(mile_per_hour, "396", "0.225") + yard_per_minute.checkWith(mile_per_hour, "396", "13.5") + yard_per_second.checkWith(mile_per_hour, "396", "810") + mile_per_hour.checkWith(foot_per_hour, "396", "2090880") + mile_per_minute.checkWith(foot_per_hour, "396", "125452800") + mile_per_second.checkWith(foot_per_hour, "396", "7527168000") + knot.checkWith(meter_per_hour, "396", "733392") + velocity_of_light_in_vacuum.checkWith(meter_per_second, "1", "299792458") + cosmic_velocity_first.checkWith(meter_per_second, "1", "7900") + cosmic_velocity_second.checkWith(meter_per_second, "1", "11200") + cosmic_velocity_third.checkWith(meter_per_second, "1", "16670") + earths_orbital_speed.checkWith(meter_per_second, "1", "29765") + mach.checkWith(meter_per_second, "1", "343.6") + mach_si_standard.checkWith(meter_per_second, "1", "295.0464") } @Test - fun testTemperature() { - MyUnitIDS.celsius.checkWith(MyUnitIDS.celsius, "0", "0") - MyUnitIDS.celsius.checkWith(MyUnitIDS.fahrenheit, "0", "32") - MyUnitIDS.celsius.checkWith(MyUnitIDS.kelvin, "0", "273.15") - MyUnitIDS.celsius.checkWith(MyUnitIDS.celsius, "36.6", "36.6") - MyUnitIDS.celsius.checkWith(MyUnitIDS.fahrenheit, "36.6", "97.88") - MyUnitIDS.celsius.checkWith(MyUnitIDS.kelvin, "36.6", "309.75") - MyUnitIDS.celsius.checkWith(MyUnitIDS.celsius, "-36.6", "-36.6") - MyUnitIDS.celsius.checkWith(MyUnitIDS.fahrenheit, "-36.6", "-33.88") - MyUnitIDS.celsius.checkWith(MyUnitIDS.kelvin, "-36.6", "236.55") + fun testTemperature() = testWithUnits { + celsius.checkWith(celsius, "0", "0") + celsius.checkWith(fahrenheit, "0", "32") + celsius.checkWith(kelvin, "0", "273.15") + celsius.checkWith(celsius, "36.6", "36.6") + celsius.checkWith(fahrenheit, "36.6", "97.88") + celsius.checkWith(kelvin, "36.6", "309.75") + celsius.checkWith(celsius, "-36.6", "-36.6") + celsius.checkWith(fahrenheit, "-36.6", "-33.88") + celsius.checkWith(kelvin, "-36.6", "236.55") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.celsius, "0", "-17.77778") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.fahrenheit, "0", "0") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.kelvin, "0", "255.37222") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.celsius, "36.6", "2.55556") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.fahrenheit, "36.6", "36.6") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.kelvin, "36.6", "275.70556") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.celsius, "-36.6", "-38.11111") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.fahrenheit, "-36.6", "-36.6") - MyUnitIDS.fahrenheit.checkWith(MyUnitIDS.kelvin, "-36.6", "235.03889") + fahrenheit.checkWith(celsius, "0", "-17.77778") + fahrenheit.checkWith(fahrenheit, "0", "0") + fahrenheit.checkWith(kelvin, "0", "255.37222") + fahrenheit.checkWith(celsius, "36.6", "2.55556") + fahrenheit.checkWith(fahrenheit, "36.6", "36.6") + fahrenheit.checkWith(kelvin, "36.6", "275.70556") + fahrenheit.checkWith(celsius, "-36.6", "-38.11111") + fahrenheit.checkWith(fahrenheit, "-36.6", "-36.6") + fahrenheit.checkWith(kelvin, "-36.6", "235.03889") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.celsius, "0", "-273.15") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.fahrenheit, "0", "-459.67") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.kelvin, "0", "0") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.celsius, "36.6", "-236.55") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.fahrenheit, "36.6", "-393.79") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.kelvin, "36.6", "36.6") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.celsius, "-36.6", "-309.75") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.fahrenheit, "-36.6", "-525.55") - MyUnitIDS.kelvin.checkWith(MyUnitIDS.kelvin, "-36.6", "-36.6") + kelvin.checkWith(celsius, "0", "-273.15") + kelvin.checkWith(fahrenheit, "0", "-459.67") + kelvin.checkWith(kelvin, "0", "0") + kelvin.checkWith(celsius, "36.6", "-236.55") + kelvin.checkWith(fahrenheit, "36.6", "-393.79") + kelvin.checkWith(kelvin, "36.6", "36.6") + kelvin.checkWith(celsius, "-36.6", "-309.75") + kelvin.checkWith(fahrenheit, "-36.6", "-525.55") + kelvin.checkWith(kelvin, "-36.6", "-36.6") } @Test - fun testTime() { - MyUnitIDS.attosecond.checkWith(MyUnitIDS.millisecond, "366000000000", "0.00037") - MyUnitIDS.nanosecond.checkWith(MyUnitIDS.millisecond, "366", "0.00037") - MyUnitIDS.microsecond.checkWith(MyUnitIDS.millisecond, "366", "0.366") - MyUnitIDS.millisecond.checkWith(MyUnitIDS.second, "366", "0.366") - MyUnitIDS.jiffy.checkWith(MyUnitIDS.second, "366", "3.66") - MyUnitIDS.second.checkWith(MyUnitIDS.millisecond, "366", "366000") - MyUnitIDS.minute.checkWith(MyUnitIDS.millisecond, "366", "21960000") - MyUnitIDS.hour.checkWith(MyUnitIDS.millisecond, "366", "1317600000") - MyUnitIDS.day.checkWith(MyUnitIDS.hour, "366", "8784") - MyUnitIDS.week.checkWith(MyUnitIDS.hour, "366", "61488") + fun testTime() = testWithUnits { + attosecond.checkWith(millisecond, "366000000000", "0.00037") + nanosecond.checkWith(millisecond, "366", "0.00037") + microsecond.checkWith(millisecond, "366", "0.366") + millisecond.checkWith(second, "366", "0.366") + jiffy.checkWith(second, "366", "3.66") + second.checkWith(millisecond, "366", "366000") + minute.checkWith(millisecond, "366", "21960000") + hour.checkWith(millisecond, "366", "1317600000") + day.checkWith(hour, "366", "8784") + week.checkWith(hour, "366", "61488") } @Test - fun testVolume() { - MyUnitIDS.attoliter.checkWith(MyUnitIDS.millimeter, "1507000000000", "0.00151") - MyUnitIDS.milliliter.checkWith(MyUnitIDS.liter, "1507", "1.507") - MyUnitIDS.liter.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "398.10728") - MyUnitIDS.us_liquid_gallon.checkWith(MyUnitIDS.us_fluid_ounce, "1507", "192896") - MyUnitIDS.us_liquid_quart.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "376.75") - MyUnitIDS.us_liquid_pint.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "188.375") - MyUnitIDS.us_legal_cup.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "94.1875") - MyUnitIDS.us_fluid_ounce.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "11.77344") - MyUnitIDS.us_tablespoon.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "5.88672") - MyUnitIDS.us_teaspoon.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "1.96224") - MyUnitIDS.imperial_gallon.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "1809.83154") - MyUnitIDS.imperial_quart.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "452.45788") - MyUnitIDS.imperial_pint.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "226.22894") - MyUnitIDS.imperial_cup.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "113.11447") - MyUnitIDS.imperial_fluid_ounce.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "11.31145") - MyUnitIDS.imperial_tablespoon.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "7.06965") - MyUnitIDS.imperial_teaspoon.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "2.35655") - MyUnitIDS.cubic_millimeter.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "0.0004") - MyUnitIDS.cubic_centimeter.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "0.39811") - MyUnitIDS.cubic_meter.checkWith(MyUnitIDS.us_liquid_gallon, "1507", "398107.2829") - MyUnitIDS.cubic_kilometer.checkWith(MyUnitIDS.us_liquid_gallon, "0.0000001507", "39810.72829") + fun testVolume() = testWithUnits { + attoliter.checkWith(millimeter, "1507000000000", "0.00151") + milliliter.checkWith(liter, "1507", "1.507") + liter.checkWith(us_liquid_gallon, "1507", "398.10728") + us_liquid_gallon.checkWith(us_fluid_ounce, "1507", "192896") + us_liquid_quart.checkWith(us_liquid_gallon, "1507", "376.75") + us_liquid_pint.checkWith(us_liquid_gallon, "1507", "188.375") + us_legal_cup.checkWith(us_liquid_gallon, "1507", "94.1875") + us_fluid_ounce.checkWith(us_liquid_gallon, "1507", "11.77344") + us_tablespoon.checkWith(us_liquid_gallon, "1507", "5.88672") + us_teaspoon.checkWith(us_liquid_gallon, "1507", "1.96224") + imperial_gallon.checkWith(us_liquid_gallon, "1507", "1809.83154") + imperial_quart.checkWith(us_liquid_gallon, "1507", "452.45788") + imperial_pint.checkWith(us_liquid_gallon, "1507", "226.22894") + imperial_cup.checkWith(us_liquid_gallon, "1507", "113.11447") + imperial_fluid_ounce.checkWith(us_liquid_gallon, "1507", "11.31145") + imperial_tablespoon.checkWith(us_liquid_gallon, "1507", "7.06965") + imperial_teaspoon.checkWith(us_liquid_gallon, "1507", "2.35655") + cubic_millimeter.checkWith(us_liquid_gallon, "1507", "0.0004") + cubic_centimeter.checkWith(us_liquid_gallon, "1507", "0.39811") + cubic_meter.checkWith(us_liquid_gallon, "1507", "398107.2829") + cubic_kilometer.checkWith(us_liquid_gallon, "0.0000001507", "39810.72829") } @Test - fun testFlux() { - MyUnitIDS.maxwell.checkWith(MyUnitIDS.milliweber, "68.2", "0.00068") - MyUnitIDS.weber.checkWith(MyUnitIDS.milliweber, "68.2", "68200") - MyUnitIDS.milliweber.checkWith(MyUnitIDS.weber, "68.2", "0.0682") - MyUnitIDS.microweber.checkWith(MyUnitIDS.milliweber, "68.2", "0.0682") - MyUnitIDS.kiloweber.checkWith(MyUnitIDS.weber, "68.2", "68200") - MyUnitIDS.megaweber.checkWith(MyUnitIDS.weber, "68.2", "68200000") - MyUnitIDS.gigaweber.checkWith(MyUnitIDS.weber, "68.2", "68200000000") + fun testFlux() = testWithUnits { + maxwell.checkWith(milliweber, "68.2", "0.00068") + weber.checkWith(milliweber, "68.2", "68200") + milliweber.checkWith(weber, "68.2", "0.0682") + microweber.checkWith(milliweber, "68.2", "0.0682") + kiloweber.checkWith(weber, "68.2", "68200") + megaweber.checkWith(weber, "68.2", "68200000") + gigaweber.checkWith(weber, "68.2", "68200000000") } @Test - fun testNumberBase() { - MyUnitIDS.binary.checkWith(MyUnitIDS.octal, "1000001001", "1011") - MyUnitIDS.ternary.checkWith(MyUnitIDS.decimal, "10112020111", "69430") - MyUnitIDS.quaternary.checkWith(MyUnitIDS.quinary, "20321", "4234") - MyUnitIDS.quinary.checkWith(MyUnitIDS.nonary, "4234", "702") - MyUnitIDS.senary.checkWith(MyUnitIDS.nonary, "4234", "1274") - MyUnitIDS.septenary.checkWith(MyUnitIDS.nonary, "4234", "2041") - MyUnitIDS.octal.checkWith(MyUnitIDS.undecimal, "42343277", "5107945") - MyUnitIDS.nonary.checkWith(MyUnitIDS.duodecimal, "42343287", "69b9a81") - MyUnitIDS.decimal.checkWith(MyUnitIDS.duodecimal, "42343287", "12220273") - MyUnitIDS.undecimal.checkWith(MyUnitIDS.hexadecimal, "4234a287", "4e3f0c2") - MyUnitIDS.duodecimal.checkWith(MyUnitIDS.hexadecimal, "4234a287", "8f30d07") - MyUnitIDS.tridecimal.checkWith(MyUnitIDS.hexadecimal, "4234a287", "f9c3ff4") - MyUnitIDS.tetradecimal.checkWith(MyUnitIDS.hexadecimal, "bb", "a5") - MyUnitIDS.pentadecimal.checkWith(MyUnitIDS.hexadecimal, "BABE", "9a82") - MyUnitIDS.hexadecimal.checkWith(MyUnitIDS.quinary, "FADE", "4023342") + fun testNumberBase() = testWithUnits { + binary.checkWith(octal, "1000001001", "1011") + ternary.checkWith(decimal, "10112020111", "69430") + quaternary.checkWith(quinary, "20321", "4234") + quinary.checkWith(nonary, "4234", "702") + senary.checkWith(nonary, "4234", "1274") + septenary.checkWith(nonary, "4234", "2041") + octal.checkWith(undecimal, "42343277", "5107945") + nonary.checkWith(duodecimal, "42343287", "69b9a81") + decimal.checkWith(duodecimal, "42343287", "12220273") + undecimal.checkWith(hexadecimal, "4234a287", "4e3f0c2") + duodecimal.checkWith(hexadecimal, "4234a287", "8f30d07") + tridecimal.checkWith(hexadecimal, "4234a287", "f9c3ff4") + tetradecimal.checkWith(hexadecimal, "bb", "a5") + pentadecimal.checkWith(hexadecimal, "BABE", "9a82") + hexadecimal.checkWith(quinary, "FADE", "4023342") } @Test - fun testElectrostaticCapacitance() { - MyUnitIDS.attofarad.checkWith(MyUnitIDS.nanofarad, "364354322342", "364.35432") - MyUnitIDS.statfarad.checkWith(MyUnitIDS.microfarad, "123312", "0.1372") - MyUnitIDS.farad.checkWith(MyUnitIDS.kilofarad, "123312", "123.312") - MyUnitIDS.exafarad.checkWith(MyUnitIDS.petafarad, "123312", "123312000") - MyUnitIDS.picofarad.checkWith(MyUnitIDS.nanofarad, "11233", "11.233") - MyUnitIDS.nanofarad.checkWith(MyUnitIDS.millifarad, "11233", "0.01123") - MyUnitIDS.microfarad.checkWith(MyUnitIDS.nanofarad, "1123433", "1123433000") - MyUnitIDS.millifarad.checkWith(MyUnitIDS.nanofarad, "112", "112000000") - MyUnitIDS.kilofarad.checkWith(MyUnitIDS.microfarad, "11132", "11132000000000") - MyUnitIDS.megafarad.checkWith(MyUnitIDS.kilofarad, "11132", "11132000") - MyUnitIDS.gigafarad.checkWith(MyUnitIDS.petafarad, "11132", "0.01113") - MyUnitIDS.petafarad.checkWith(MyUnitIDS.kilofarad, "11132", "11132000000000000") + fun testElectrostaticCapacitance() = testWithUnits { + attofarad.checkWith(nanofarad, "364354322342", "364.35432") + statfarad.checkWith(microfarad, "123312", "0.1372") + farad.checkWith(kilofarad, "123312", "123.312") + exafarad.checkWith(petafarad, "123312", "123312000") + picofarad.checkWith(nanofarad, "11233", "11.233") + nanofarad.checkWith(millifarad, "11233", "0.01123") + microfarad.checkWith(nanofarad, "1123433", "1123433000") + millifarad.checkWith(nanofarad, "112", "112000000") + kilofarad.checkWith(microfarad, "11132", "11132000000000") + megafarad.checkWith(kilofarad, "11132", "11132000") + gigafarad.checkWith(petafarad, "11132", "0.01113") + petafarad.checkWith(kilofarad, "11132", "11132000000000000") } private fun String.checkWith(checkingId: String, value: String, expected: String) { @@ -415,4 +415,6 @@ class AllUnitsTest { // GROUP : testedCount / totalCount println("${unitGroup.name} : ${history[unitGroup]?.size} / ${allUnitsRepository.getCollectionByGroup(unitGroup).size}") } + + private fun testWithUnits(block: MyUnitIDS.() -> Unit): Unit = with(MyUnitIDS, block = block) } From 4a646a0a7e99cdeb0d7aff6cc52d37a3b047b6d3 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Wed, 22 Mar 2023 17:26:38 +0300 Subject: [PATCH 07/12] Added prefixes (#30) --- core/base/src/main/res/values/strings.xml | 53 ++++++++++++++++++ .../sadellie/unitto/data/model/UnitGroup.kt | 3 +- .../unitto/data/units/AllUnitsRepository.kt | 4 +- .../sadellie/unitto/data/units/MyUnitIDS.kt | 27 +++++++++ .../unitto/data/units/collections/Prefix.kt | 56 +++++++++++++++++++ .../unitto/data/units/AllUnitsTest.kt | 29 ++++++++++ 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index 8c452c10..b4c96438 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -997,6 +997,58 @@ Petafarad PF + + Quetta + Q + Ronna + R + Yotta + Y + Zetta + Z + Exa + E + Peta + P + Tera + T + Giga + G + Mega + M + Kilo + k + Hecto + h + Deca + da + Base + Base + Deci + d + Centi + c + Milli + m + Micro + μ + Nano + n + Pico + p + Femto + f + Atto + a + Zepto + z + Yocto + y + Ronto + r + Quecto + q + Length Time @@ -1016,6 +1068,7 @@ Flux Base Capacitance + Prefix Convert from diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt index 22250ef7..55c3b3c7 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt @@ -48,5 +48,6 @@ enum class UnitGroup( DATA_TRANSFER(res = R.string.data_transfer), FLUX(res = R.string.flux), NUMBER_BASE(res = R.string.number_base), - ELECTROSTATIC_CAPACITANCE(res = R.string.electrostatic_capacitance) + ELECTROSTATIC_CAPACITANCE(res = R.string.electrostatic_capacitance), + PREFIX(res = R.string.prefix), } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt index 980ee487..27f541a7 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt @@ -42,6 +42,7 @@ import com.sadellie.unitto.data.units.collections.timeCollection import com.sadellie.unitto.data.units.collections.volumeCollection import com.sadellie.unitto.data.database.UnitsEntity import com.sadellie.unitto.data.units.collections.electrostaticCapacitance +import com.sadellie.unitto.data.units.collections.prefix import java.math.BigDecimal import javax.inject.Inject import javax.inject.Singleton @@ -80,7 +81,8 @@ class AllUnitsRepository @Inject constructor() { UnitGroup.DATA_TRANSFER to dataTransferCollection, UnitGroup.FLUX to fluxCollection, UnitGroup.NUMBER_BASE to numberBaseCollection, - UnitGroup.ELECTROSTATIC_CAPACITANCE to electrostaticCapacitance + UnitGroup.ELECTROSTATIC_CAPACITANCE to electrostaticCapacitance, + UnitGroup.PREFIX to prefix, ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt index ab64fac5..9d671493 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt @@ -530,4 +530,31 @@ object MyUnitIDS { const val megafarad = "megafarad" const val gigafarad = "gigafarad" const val petafarad = "petafarad" + + // PREFIX + const val prefix_quetta = "quetta" + const val prefix_ronna = "ronna" + const val prefix_yotta = "yotta" + const val prefix_zetta = "zetta" + const val prefix_exa = "exa" + const val prefix_peta = "peta" + const val prefix_tera = "tera" + const val prefix_giga = "giga" + const val prefix_mega = "mega" + const val prefix_kilo = "kilo" + const val prefix_hecto = "hecto" + const val prefix_deca = "deca" + const val prefix_base = "base" + const val prefix_deci = "deci" + const val prefix_centi = "centi" + const val prefix_milli = "milli" + const val prefix_micro = "micro" + const val prefix_nano = "nano" + const val prefix_pico = "pico" + const val prefix_femto = "femto" + const val prefix_atto = "atto" + const val prefix_zepto = "zepto" + const val prefix_yocto = "yocto" + const val prefix_ronto = "ronto" + const val prefix_quecto = "quecto" } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt new file mode 100644 index 00000000..bbe3f6b7 --- /dev/null +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt @@ -0,0 +1,56 @@ +/* + * 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.units.collections + +import com.sadellie.unitto.data.model.AbstractUnit +import com.sadellie.unitto.data.model.MyUnit +import com.sadellie.unitto.data.model.UnitGroup +import com.sadellie.unitto.data.units.MyUnitIDS +import com.sadellie.unitto.data.units.R +import java.math.BigDecimal + +val prefix: List by lazy { + listOf( + MyUnit(MyUnitIDS.prefix_quetta, BigDecimal.valueOf(1E+30), UnitGroup.PREFIX, R.string.prefix_quetta, R.string.prefix_quetta_short), + MyUnit(MyUnitIDS.prefix_ronna, BigDecimal.valueOf(1E+27), UnitGroup.PREFIX, R.string.prefix_ronna, R.string.prefix_ronna_short), + MyUnit(MyUnitIDS.prefix_yotta, BigDecimal.valueOf(1E+24), UnitGroup.PREFIX, R.string.prefix_yotta, R.string.prefix_yotta_short), + MyUnit(MyUnitIDS.prefix_zetta, BigDecimal.valueOf(1E+21), UnitGroup.PREFIX, R.string.prefix_zetta, R.string.prefix_zetta_short), + MyUnit(MyUnitIDS.prefix_exa, BigDecimal.valueOf(1E+18), UnitGroup.PREFIX, R.string.prefix_exa, R.string.prefix_exa_short), + MyUnit(MyUnitIDS.prefix_peta, BigDecimal.valueOf(1E+15), UnitGroup.PREFIX, R.string.prefix_peta, R.string.prefix_peta_short), + MyUnit(MyUnitIDS.prefix_tera, BigDecimal.valueOf(1E+12), UnitGroup.PREFIX, R.string.prefix_tera, R.string.prefix_tera_short), + MyUnit(MyUnitIDS.prefix_giga, BigDecimal.valueOf(1E+9), UnitGroup.PREFIX, R.string.prefix_giga, R.string.prefix_giga_short), + MyUnit(MyUnitIDS.prefix_mega, BigDecimal.valueOf(1E+6), UnitGroup.PREFIX, R.string.prefix_mega, R.string.prefix_mega_short), + MyUnit(MyUnitIDS.prefix_kilo, BigDecimal.valueOf(1E+3), UnitGroup.PREFIX, R.string.prefix_kilo, R.string.prefix_kilo_short), + MyUnit(MyUnitIDS.prefix_hecto, BigDecimal.valueOf(1E+2), UnitGroup.PREFIX, R.string.prefix_hecto, R.string.prefix_hecto_short), + MyUnit(MyUnitIDS.prefix_deca, BigDecimal.valueOf(1E+1), UnitGroup.PREFIX, R.string.prefix_deca, R.string.prefix_deca_short), + MyUnit(MyUnitIDS.prefix_base, BigDecimal.valueOf(1E+0), UnitGroup.PREFIX, R.string.prefix_base, R.string.prefix_base_short), + MyUnit(MyUnitIDS.prefix_deci, BigDecimal.valueOf(1E-1), UnitGroup.PREFIX, R.string.prefix_deci, R.string.prefix_deci_short), + MyUnit(MyUnitIDS.prefix_centi, BigDecimal.valueOf(1E-2), UnitGroup.PREFIX, R.string.prefix_centi, R.string.prefix_centi_short), + MyUnit(MyUnitIDS.prefix_milli, BigDecimal.valueOf(1E-3), UnitGroup.PREFIX, R.string.prefix_milli, R.string.prefix_milli_short), + MyUnit(MyUnitIDS.prefix_micro, BigDecimal.valueOf(1E-6), UnitGroup.PREFIX, R.string.prefix_micro, R.string.prefix_micro_short), + MyUnit(MyUnitIDS.prefix_nano, BigDecimal.valueOf(1E-9), UnitGroup.PREFIX, R.string.prefix_nano, R.string.prefix_nano_short), + MyUnit(MyUnitIDS.prefix_pico, BigDecimal.valueOf(1E-12), UnitGroup.PREFIX, R.string.prefix_pico, R.string.prefix_pico_short), + MyUnit(MyUnitIDS.prefix_femto, BigDecimal.valueOf(1E-15), UnitGroup.PREFIX, R.string.prefix_femto, R.string.prefix_femto_short), + MyUnit(MyUnitIDS.prefix_atto, BigDecimal.valueOf(1E-18), UnitGroup.PREFIX, R.string.prefix_atto, R.string.prefix_atto_short), + MyUnit(MyUnitIDS.prefix_zepto, BigDecimal.valueOf(1E-21), UnitGroup.PREFIX, R.string.prefix_zepto, R.string.prefix_zepto_short), + MyUnit(MyUnitIDS.prefix_yocto, BigDecimal.valueOf(1E-24), UnitGroup.PREFIX, R.string.prefix_yocto, R.string.prefix_yocto_short), + MyUnit(MyUnitIDS.prefix_ronto, BigDecimal.valueOf(1E-27), UnitGroup.PREFIX, R.string.prefix_ronto, R.string.prefix_ronto_short), + MyUnit(MyUnitIDS.prefix_quecto, BigDecimal.valueOf(1E-30), UnitGroup.PREFIX, R.string.prefix_quecto, R.string.prefix_quecto_short), + ) +} 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 69d50051..ae569b76 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 @@ -391,6 +391,35 @@ class AllUnitsTest { petafarad.checkWith(kilofarad, "11132", "11132000000000000") } + @Test + fun testPrefix() = testWithUnits { + prefix_quetta.checkWith(prefix_base, "1", "1000000000000000000000000000000") + prefix_ronna.checkWith(prefix_base, "1", "1000000000000000000000000000") + prefix_yotta.checkWith(prefix_base, "1", "1000000000000000000000000") + prefix_zetta.checkWith(prefix_base, "1", "1000000000000000000000") + prefix_exa.checkWith(prefix_base, "1", "1000000000000000000") + prefix_peta.checkWith(prefix_base, "1", "1000000000000000") + prefix_tera.checkWith(prefix_base, "1", "1000000000000") + prefix_giga.checkWith(prefix_base, "1", "1000000000") + prefix_mega.checkWith(prefix_base, "1", "1000000") + prefix_kilo.checkWith(prefix_base, "1", "1000") + prefix_hecto.checkWith(prefix_base, "1", "100") + prefix_deca.checkWith(prefix_base, "1", "10") + prefix_base.checkWith(prefix_base, "77777", "77777") + prefix_deci.checkWith(prefix_base, "1", "0.1") + prefix_centi.checkWith(prefix_base, "1", "0.01") + prefix_milli.checkWith(prefix_base, "1", "0.001") + prefix_micro.checkWith(prefix_base, "1", "0.000001") + prefix_nano.checkWith(prefix_base, "1", "0.000000001") + prefix_pico.checkWith(prefix_base, "1", "0.000000000001") + prefix_femto.checkWith(prefix_base, "1", "0.000000000000001") + prefix_atto.checkWith(prefix_base, "1", "0.000000000000000001") + prefix_zepto.checkWith(prefix_base, "1", "0.000000000000000000001") + prefix_yocto.checkWith(prefix_base, "1", "0.000000000000000000000001") + prefix_ronto.checkWith(prefix_base, "1", "0.000000000000000000000000001") + prefix_quecto.checkWith(prefix_base, "1", "0.000000000000000000000000000001") + } + private fun String.checkWith(checkingId: String, value: String, expected: String) { val unitFrom = allUnitsRepository.getById(this) val unitTo = allUnitsRepository.getById(checkingId) From 273cbcc0ff55c966c62835d9f8445aee178bdf9c Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Thu, 23 Mar 2023 13:41:46 +0300 Subject: [PATCH 08/12] Added force (#29) --- core/base/src/main/res/values/strings.xml | 33 +++++++++++++ .../sadellie/unitto/data/model/UnitGroup.kt | 1 + .../unitto/data/units/AllUnitsRepository.kt | 2 + .../sadellie/unitto/data/units/MyUnitIDS.kt | 17 +++++++ .../unitto/data/units/collections/Force.kt | 46 +++++++++++++++++++ .../unitto/data/units/AllUnitsTest.kt | 19 ++++++++ 6 files changed, 118 insertions(+) create mode 100644 data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index b4c96438..ad211742 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -1049,6 +1049,38 @@ Quecto q + + Newton + N + Kilonewton + kN + Gram-force + gf + Kilogram-force + kgf + Ton-force + tf + Millinewton + mN + attonewton + aN + dyne + dyn + Joule/meter + J/m + Joule/centimeter + J/cm + Kilopound-force + kipf + Pound-force + lbf + Ounce-force + ozf + Pond + p + Kilopond + kp + Length Time @@ -1069,6 +1101,7 @@ Base Capacitance Prefix + Force Convert from diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt index 55c3b3c7..452e3d40 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt @@ -50,4 +50,5 @@ enum class UnitGroup( NUMBER_BASE(res = R.string.number_base), ELECTROSTATIC_CAPACITANCE(res = R.string.electrostatic_capacitance), PREFIX(res = R.string.prefix), + FORCE(res = R.string.force), } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt index 27f541a7..a81c6500 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt @@ -42,6 +42,7 @@ import com.sadellie.unitto.data.units.collections.timeCollection import com.sadellie.unitto.data.units.collections.volumeCollection import com.sadellie.unitto.data.database.UnitsEntity import com.sadellie.unitto.data.units.collections.electrostaticCapacitance +import com.sadellie.unitto.data.units.collections.forceCollection import com.sadellie.unitto.data.units.collections.prefix import java.math.BigDecimal import javax.inject.Inject @@ -83,6 +84,7 @@ class AllUnitsRepository @Inject constructor() { UnitGroup.NUMBER_BASE to numberBaseCollection, UnitGroup.ELECTROSTATIC_CAPACITANCE to electrostaticCapacitance, UnitGroup.PREFIX to prefix, + UnitGroup.FORCE to forceCollection, ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt index 9d671493..fc9ba7c9 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt @@ -557,4 +557,21 @@ object MyUnitIDS { const val prefix_yocto = "yocto" const val prefix_ronto = "ronto" const val prefix_quecto = "quecto" + + // FORCE + const val newton = "newton" + const val kilonewton = "kilonewton" + const val gram_force = "gram_force" + const val kilogram_force = "kilogram_force" + const val ton_force = "ton_force" + const val millinewton = "millinewton" + const val attonewton = "attonewton" + const val dyne = "dyne" + const val joule_per_meter = "joule_per_meter" + const val joule_per_centimeter = "joule_per_centimeter" + const val kilopound_force = "kilopound_force" + const val pound_force = "pound_force" + const val ounce_force = "ounce_force" + const val pond = "pond" + const val kilopond = "kilopond" } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt new file mode 100644 index 00000000..647ba164 --- /dev/null +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt @@ -0,0 +1,46 @@ +/* + * 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.units.collections + +import com.sadellie.unitto.data.model.AbstractUnit +import com.sadellie.unitto.data.model.MyUnit +import com.sadellie.unitto.data.model.UnitGroup +import com.sadellie.unitto.data.units.MyUnitIDS +import com.sadellie.unitto.data.units.R +import java.math.BigDecimal + +val forceCollection: List by lazy { + listOf( + MyUnit(MyUnitIDS.newton, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.newton, R.string.newton_short), + MyUnit(MyUnitIDS.kilonewton, BigDecimal.valueOf(1E+21), UnitGroup.FORCE, R.string.kilonewton, R.string.kilonewton_short), + MyUnit(MyUnitIDS.gram_force, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.gram_force, R.string.gram_force_short), + MyUnit(MyUnitIDS.kilogram_force, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilogram_force, R.string.kilogram_force_short), + MyUnit(MyUnitIDS.ton_force, BigDecimal.valueOf(9.80665E+21), UnitGroup.FORCE, R.string.ton_force, R.string.ton_force_short), + MyUnit(MyUnitIDS.millinewton, BigDecimal.valueOf(1E+15), UnitGroup.FORCE, R.string.millinewton, R.string.millinewton_short), + MyUnit(MyUnitIDS.attonewton, BigDecimal.valueOf(1), UnitGroup.FORCE, R.string.attonewton, R.string.attonewton_short), + MyUnit(MyUnitIDS.dyne, BigDecimal.valueOf(1E+13), UnitGroup.FORCE, R.string.dyne, R.string.dyne_short), + MyUnit(MyUnitIDS.joule_per_meter, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.joule_per_meter, R.string.joule_per_meter_short), + MyUnit(MyUnitIDS.joule_per_centimeter, BigDecimal.valueOf(1E+16), UnitGroup.FORCE, R.string.joule_per_centimeter, R.string.joule_per_centimeter_short), + MyUnit(MyUnitIDS.kilopound_force, BigDecimal.valueOf(4.448221615255E+21), UnitGroup.FORCE, R.string.kilopound_force, R.string.kilopound_force_short), + MyUnit(MyUnitIDS.pound_force, BigDecimal.valueOf(4.4482216152550001E18), UnitGroup.FORCE, R.string.pound_force, R.string.pound_force_short), + MyUnit(MyUnitIDS.ounce_force, BigDecimal.valueOf(2.78013850953423008E17), UnitGroup.FORCE, R.string.ounce_force, R.string.ounce_force_short), + MyUnit(MyUnitIDS.pond, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.pond, R.string.pond_short), + MyUnit(MyUnitIDS.kilopond, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilopond, R.string.kilopond_short), + ) +} 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 ae569b76..29087877 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 @@ -420,6 +420,25 @@ class AllUnitsTest { prefix_quecto.checkWith(prefix_base, "1", "0.000000000000000000000000000001") } + @Test + fun testForce() = testWithUnits { + newton.checkWith(pond, "6553", "668220.03436") + kilonewton.checkWith(kilopound_force, "6553", "1473.173") + gram_force.checkWith(kilonewton, "6553", "0.06426") + kilogram_force.checkWith(ton_force, "6553", "6.553") + ton_force.checkWith(millinewton, "6553", "64262977450") + millinewton.checkWith(kilonewton, "6553", "0.00655") + attonewton.checkWith(dyne, "6553123123", "0.00066") + dyne.checkWith(joule_per_meter, "6553", "0.06553") + joule_per_meter.checkWith(pond, "6553", "668220.03436") + joule_per_centimeter.checkWith(kilopond, "6553", "6.6822") + kilopound_force.checkWith(kilopond, "6553", "2972390.80061") + pound_force.checkWith(ounce_force, "6553", "104848") + ounce_force.checkWith(pound_force, "6553", "409.5625") + pond.checkWith(kilonewton, "6553", "0.06426") + kilopond.checkWith(kilonewton, "6553", "64.26298") + } + private fun String.checkWith(checkingId: String, value: String, expected: String) { val unitFrom = allUnitsRepository.getById(this) val unitTo = allUnitsRepository.getById(checkingId) From 6b58f112c3e5b6fc266a094c7afe8fb31834767c Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Thu, 23 Mar 2023 13:47:41 +0300 Subject: [PATCH 09/12] Clean up - "/" instead of "per" in unit names (only EN (US)) - Code improvements --- core/base/src/main/res/values/strings.xml | 106 +++++++++--------- .../unitto/data/units/AllUnitsRepository.kt | 10 +- .../unitto/data/units/collections/Prefix.kt | 2 +- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index ad211742..11b31333 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -122,47 +122,47 @@ K - Millimeter per hour + Millimeter/hour mm/h - Millimeter per minute + Millimeter/minute mm/m - Millimeter per second + Millimeter/second mm/s - Centimeter per hour + Centimeter/hour cm/h - Centimeter per minute + Centimeter/minute cm/m - Centimeter per second + Centimeter/second cm/s - Meter per hour + Meter/hour m/h - Meter per minute + Meter/minute m/m - Meter per second + Meter/second m/s - Kilometer per hour + Kilometer/hour km/h - Kilometer per minute + Kilometer/minute km/m - Kilometer per second + Kilometer/second km/s - Foot per hour + Foot/hour ft/h - Foot per minute + Foot/minute ft/m - Foot per second + Foot/second ft/s - Yard per hour + Yard/hour yd/h - Yard per minute + Yard/minute yd/m - Yard per second + Yard/second yd/s - Mile per hour + Mile/hour mi/h - Mile per minute + Mile/minute mi/m - Mile per second + Mile/second mi/s Knot kt @@ -220,41 +220,41 @@ EB - Bit per second + Bit/second b/s - Kibibit per second + Kibibit/second Kib/s - Kilobit per second + Kilobit/second Kb/s - Megabit per second + Megabit/second Mb/s - Mebibit per second + Mebibit/second Mib/s - Gigabit per second + Gigabit/second Gb/s - Terabit per second + Terabit/second Tb/s - Petabit per second + Petabit/second Pb/s - Exabit per second + Exabit/second Eb/s - Byte per second + Byte/second B/s - Kibibyte per second + Kibibyte/second KiB/s - Kilobyte per second + Kilobyte/second KB/s - Megabyte per second + Megabyte/second MB/s - Mebibyte per second + Mebibyte/second MiB/s - Gigabyte per second + Gigabyte/second GB/s - Terabyte per second + Terabyte/second TB/s - Petabyte per second + Petabyte/second PB/s - Exabyte per second + Exabyte/second EB/s @@ -446,9 +446,9 @@ PPa Exapascal EPa - Pound per square inch + Pound/square inch psi - Kilopound per square inch + Kilopound/square inch ksi Standard atmosphere atm @@ -460,29 +460,29 @@ mm Hg - Attometer per square second + Attometer/square second am/s^2 - Femtometer per square second + Femtometer/square second fm/s^2 - Picometer per square second + Picometer/square second pm/s^2 - Nanometer per square second + Nanometer/square second nm/s^2 - Micrometer per square second + Micrometer/square second µm/s^2 - Millimeter per square second + Millimeter/square second mm/s^2 - Centimeter per square second + Centimeter/square second cm/s^2 - Decimeter per square second + Decimeter/square second dm/s^2 - Meter per square second + Meter/square second m/s^2 - Kilometer per square second + Kilometer/square second km/s^2 - Dekameter per square second + Dekameter/square second dam/s^2 - Hectometer per square second + Hectometer/square second hm/s^2 Gal Gal diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt index a81c6500..20a3c9cd 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt @@ -20,6 +20,7 @@ package com.sadellie.unitto.data.units import android.content.Context import com.sadellie.unitto.core.base.MAX_PRECISION +import com.sadellie.unitto.data.database.UnitsEntity import com.sadellie.unitto.data.model.AbstractUnit import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.sortByLev @@ -29,21 +30,20 @@ import com.sadellie.unitto.data.units.collections.areaCollection import com.sadellie.unitto.data.units.collections.currencyCollection import com.sadellie.unitto.data.units.collections.dataCollection import com.sadellie.unitto.data.units.collections.dataTransferCollection +import com.sadellie.unitto.data.units.collections.electrostaticCapacitance import com.sadellie.unitto.data.units.collections.energyCollection import com.sadellie.unitto.data.units.collections.fluxCollection +import com.sadellie.unitto.data.units.collections.forceCollection import com.sadellie.unitto.data.units.collections.lengthCollection import com.sadellie.unitto.data.units.collections.massCollection import com.sadellie.unitto.data.units.collections.numberBaseCollection import com.sadellie.unitto.data.units.collections.powerCollection +import com.sadellie.unitto.data.units.collections.prefixCollection import com.sadellie.unitto.data.units.collections.pressureCollection import com.sadellie.unitto.data.units.collections.speedCollection import com.sadellie.unitto.data.units.collections.temperatureCollection import com.sadellie.unitto.data.units.collections.timeCollection import com.sadellie.unitto.data.units.collections.volumeCollection -import com.sadellie.unitto.data.database.UnitsEntity -import com.sadellie.unitto.data.units.collections.electrostaticCapacitance -import com.sadellie.unitto.data.units.collections.forceCollection -import com.sadellie.unitto.data.units.collections.prefix import java.math.BigDecimal import javax.inject.Inject import javax.inject.Singleton @@ -83,7 +83,7 @@ class AllUnitsRepository @Inject constructor() { UnitGroup.FLUX to fluxCollection, UnitGroup.NUMBER_BASE to numberBaseCollection, UnitGroup.ELECTROSTATIC_CAPACITANCE to electrostaticCapacitance, - UnitGroup.PREFIX to prefix, + UnitGroup.PREFIX to prefixCollection, UnitGroup.FORCE to forceCollection, ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt index bbe3f6b7..45541d76 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt @@ -25,7 +25,7 @@ import com.sadellie.unitto.data.units.MyUnitIDS import com.sadellie.unitto.data.units.R import java.math.BigDecimal -val prefix: List by lazy { +val prefixCollection: List by lazy { listOf( MyUnit(MyUnitIDS.prefix_quetta, BigDecimal.valueOf(1E+30), UnitGroup.PREFIX, R.string.prefix_quetta, R.string.prefix_quetta_short), MyUnit(MyUnitIDS.prefix_ronna, BigDecimal.valueOf(1E+27), UnitGroup.PREFIX, R.string.prefix_ronna, R.string.prefix_ronna_short), From 06af4e1a2adedf00e72d861e50d8f065e8b9b68a Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Thu, 23 Mar 2023 19:13:25 +0300 Subject: [PATCH 10/12] Added torque (#29) --- core/base/src/main/res/values/strings.xml | 37 ++++++++++++++ .../sadellie/unitto/data/model/UnitGroup.kt | 1 + .../unitto/data/units/AllUnitsRepository.kt | 2 + .../sadellie/unitto/data/units/MyUnitIDS.kt | 19 ++++++++ .../unitto/data/units/collections/Torque.kt | 48 +++++++++++++++++++ .../unitto/data/units/AllUnitsTest.kt | 21 ++++++++ 6 files changed, 128 insertions(+) create mode 100644 data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index 11b31333..5f0d9e45 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -1081,6 +1081,42 @@ Kilopond kp + + Newton meter + N*m + Newton centimeter + N*cm + Newton millimeter + N*mm + Kilonewton meter + kN*m + Dyne meter + dyn*m + Dyne centimeter + dyn*cm + Dyne millimeter + dyn*mm + Kilogram-force meter + kgf*m + Kilogram-force centimeter + kgf*cm + Kilogram-force millimeter + kgf*mm + Gram-force meter + gf*m + Gram-force centimeter + gf*cm + Gram-force millimeter + gf*mm + Ounce-force foot + ozf*ft + Ounce-force inch + ozf*in + Pound-force foot + lbf*ft + Pound-force inch + lbf*in + Length Time @@ -1102,6 +1138,7 @@ Capacitance Prefix Force + Torque Convert from diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt index 452e3d40..ebc7000f 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/UnitGroup.kt @@ -51,4 +51,5 @@ enum class UnitGroup( ELECTROSTATIC_CAPACITANCE(res = R.string.electrostatic_capacitance), PREFIX(res = R.string.prefix), FORCE(res = R.string.force), + TORQUE(res = R.string.torque), } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt index 20a3c9cd..d1df129b 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt @@ -43,6 +43,7 @@ import com.sadellie.unitto.data.units.collections.pressureCollection import com.sadellie.unitto.data.units.collections.speedCollection import com.sadellie.unitto.data.units.collections.temperatureCollection import com.sadellie.unitto.data.units.collections.timeCollection +import com.sadellie.unitto.data.units.collections.torqueCollection import com.sadellie.unitto.data.units.collections.volumeCollection import java.math.BigDecimal import javax.inject.Inject @@ -85,6 +86,7 @@ class AllUnitsRepository @Inject constructor() { UnitGroup.ELECTROSTATIC_CAPACITANCE to electrostaticCapacitance, UnitGroup.PREFIX to prefixCollection, UnitGroup.FORCE to forceCollection, + UnitGroup.TORQUE to torqueCollection ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt index fc9ba7c9..cd9e5ed4 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/MyUnitIDS.kt @@ -574,4 +574,23 @@ object MyUnitIDS { const val ounce_force = "ounce_force" const val pond = "pond" const val kilopond = "kilopond" + + // TORQUE + const val newton_meter = "newton_meter" + const val newton_centimeter = "newton_centimeter" + const val newton_millimeter = "newton_millimeter" + const val kilonewton_meter = "kilonewton_meter" + const val dyne_meter = "dyne_meter" + const val dyne_centimeter = "dyne_centimeter" + const val dyne_millimeter = "dyne_millimeter" + const val kilogram_force_meter = "kilogram_force_meter" + const val kilogram_force_centimeter = "kilogram_force_centimeter" + const val kilogram_force_millimeter = "kilogram_force_millimeter" + const val gram_force_meter = "gram_force_meter" + const val gram_force_centimeter = "gram_force_centimeter" + const val gram_force_millimeter = "gram_force_millimeter" + const val ounce_force_foot = "ounce_force_foot" + const val ounce_force_inch = "ounce_force_inch" + const val pound_force_foot = "pound_force_foot" + const val pound_force_inch = "pound_force_inch" } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt new file mode 100644 index 00000000..cb945d03 --- /dev/null +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt @@ -0,0 +1,48 @@ +/* + * 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.units.collections + +import com.sadellie.unitto.data.model.AbstractUnit +import com.sadellie.unitto.data.model.MyUnit +import com.sadellie.unitto.data.model.UnitGroup +import com.sadellie.unitto.data.units.MyUnitIDS +import com.sadellie.unitto.data.units.R +import java.math.BigDecimal + +val torqueCollection: List by lazy { + listOf( + MyUnit(MyUnitIDS.dyne_millimeter, BigDecimal.valueOf(1), UnitGroup.TORQUE, R.string.dyne_millimeter, R.string.dyne_millimeter_short), + MyUnit(MyUnitIDS.dyne_centimeter, BigDecimal.valueOf(10), UnitGroup.TORQUE, R.string.dyne_centimeter, R.string.dyne_centimeter_short), + MyUnit(MyUnitIDS.dyne_meter, BigDecimal.valueOf(1000), UnitGroup.TORQUE, R.string.dyne_meter, R.string.dyne_meter_short), + MyUnit(MyUnitIDS.newton_millimeter, BigDecimal.valueOf(100000), UnitGroup.TORQUE, R.string.newton_millimeter, R.string.newton_millimeter_short), + MyUnit(MyUnitIDS.newton_centimeter, BigDecimal.valueOf(1000000), UnitGroup.TORQUE, R.string.newton_centimeter, R.string.newton_centimeter_short), + MyUnit(MyUnitIDS.newton_meter, BigDecimal.valueOf(100000000), UnitGroup.TORQUE, R.string.newton_meter, R.string.newton_meter_short), + MyUnit(MyUnitIDS.kilonewton_meter, BigDecimal.valueOf(100000000000), UnitGroup.TORQUE, R.string.kilonewton_meter, R.string.kilonewton_meter_short), + MyUnit(MyUnitIDS.gram_force_millimeter, BigDecimal.valueOf(980.665), UnitGroup.TORQUE, R.string.gram_force_millimeter, R.string.gram_force_millimeter_short), + MyUnit(MyUnitIDS.gram_force_centimeter, BigDecimal.valueOf(9806.65), UnitGroup.TORQUE, R.string.gram_force_centimeter, R.string.gram_force_centimeter_short), + MyUnit(MyUnitIDS.kilogram_force_millimeter, BigDecimal.valueOf(980665), UnitGroup.TORQUE, R.string.kilogram_force_millimeter, R.string.kilogram_force_millimeter_short), + MyUnit(MyUnitIDS.gram_force_meter, BigDecimal.valueOf(980665), UnitGroup.TORQUE, R.string.gram_force_meter, R.string.gram_force_meter_short), + MyUnit(MyUnitIDS.kilogram_force_centimeter, BigDecimal.valueOf(9806650), UnitGroup.TORQUE, R.string.kilogram_force_centimeter, R.string.kilogram_force_centimeter_short), + MyUnit(MyUnitIDS.kilogram_force_meter, BigDecimal.valueOf(980665000), UnitGroup.TORQUE, R.string.kilogram_force_meter, R.string.kilogram_force_meter_short), + MyUnit(MyUnitIDS.ounce_force_foot, BigDecimal.valueOf(8473862.4), UnitGroup.TORQUE, R.string.ounce_force_foot, R.string.ounce_force_foot_short), + MyUnit(MyUnitIDS.ounce_force_inch, BigDecimal.valueOf(706155.2), UnitGroup.TORQUE, R.string.ounce_force_inch, R.string.ounce_force_inch_short), + MyUnit(MyUnitIDS.pound_force_foot, BigDecimal.valueOf(135581800), UnitGroup.TORQUE, R.string.pound_force_foot, R.string.pound_force_foot_short), + MyUnit(MyUnitIDS.pound_force_inch, BigDecimal.valueOf(1.1298483333333334E7), UnitGroup.TORQUE, R.string.pound_force_inch, R.string.pound_force_inch_short), + ) +} 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 29087877..3bd3347e 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 @@ -439,6 +439,27 @@ class AllUnitsTest { kilopond.checkWith(kilonewton, "6553", "64.26298") } + @Test + fun testTorque() = testWithUnits { + newton_meter.checkWith(dyne_meter, "2134", "213400000") + newton_centimeter.checkWith(kilogram_force_millimeter, "2345", "2391.23452") + newton_millimeter.checkWith(pound_force_inch, "2345", "20.755") + kilonewton_meter.checkWith(kilogram_force_meter, "2134", "217607.43985") + dyne_meter.checkWith(newton_centimeter, "2134", "2.134") + dyne_centimeter.checkWith(gram_force_centimeter, "2134", "2.17607") + dyne_millimeter.checkWith(gram_force_millimeter, "2134", "2.17607") + kilogram_force_meter.checkWith(dyne_millimeter, "2134", "2092739110000") + kilogram_force_centimeter.checkWith(gram_force_meter, "2134", "21340") + kilogram_force_millimeter.checkWith(ounce_force_inch, "2134", "2963.56822") + gram_force_meter.checkWith(newton_millimeter, "2134", "20927.3911") + gram_force_centimeter.checkWith(kilogram_force_centimeter, "2134", "2.134") + gram_force_millimeter.checkWith(kilonewton_meter, "2134", "0.00002") + ounce_force_foot.checkWith(kilogram_force_millimeter, "2134", "18439.75503") + ounce_force_inch.checkWith(dyne_meter, "2134", "1506935.1968") + pound_force_foot.checkWith(newton_millimeter, "2134", "2893315.612") + pound_force_inch.checkWith(ounce_force_foot, "2134", "2845.33337") + } + private fun String.checkWith(checkingId: String, value: String, expected: String) { val unitFrom = allUnitsRepository.getById(this) val unitTo = allUnitsRepository.getById(checkingId) From 2122aef79012cd2b25649e91cb44338155f7f058 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Thu, 23 Mar 2023 19:14:52 +0300 Subject: [PATCH 11/12] Clean up Force.kt --- .../unitto/data/units/collections/Force.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt index 647ba164..b8820adc 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt @@ -27,19 +27,19 @@ import java.math.BigDecimal val forceCollection: List by lazy { listOf( + MyUnit(MyUnitIDS.attonewton, BigDecimal.valueOf(1), UnitGroup.FORCE, R.string.attonewton, R.string.attonewton_short), + MyUnit(MyUnitIDS.dyne, BigDecimal.valueOf(1E+13), UnitGroup.FORCE, R.string.dyne, R.string.dyne_short), + MyUnit(MyUnitIDS.millinewton, BigDecimal.valueOf(1E+15), UnitGroup.FORCE, R.string.millinewton, R.string.millinewton_short), + MyUnit(MyUnitIDS.joule_per_centimeter, BigDecimal.valueOf(1E+16), UnitGroup.FORCE, R.string.joule_per_centimeter, R.string.joule_per_centimeter_short), MyUnit(MyUnitIDS.newton, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.newton, R.string.newton_short), + MyUnit(MyUnitIDS.joule_per_meter, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.joule_per_meter, R.string.joule_per_meter_short), MyUnit(MyUnitIDS.kilonewton, BigDecimal.valueOf(1E+21), UnitGroup.FORCE, R.string.kilonewton, R.string.kilonewton_short), MyUnit(MyUnitIDS.gram_force, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.gram_force, R.string.gram_force_short), MyUnit(MyUnitIDS.kilogram_force, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilogram_force, R.string.kilogram_force_short), MyUnit(MyUnitIDS.ton_force, BigDecimal.valueOf(9.80665E+21), UnitGroup.FORCE, R.string.ton_force, R.string.ton_force_short), - MyUnit(MyUnitIDS.millinewton, BigDecimal.valueOf(1E+15), UnitGroup.FORCE, R.string.millinewton, R.string.millinewton_short), - MyUnit(MyUnitIDS.attonewton, BigDecimal.valueOf(1), UnitGroup.FORCE, R.string.attonewton, R.string.attonewton_short), - MyUnit(MyUnitIDS.dyne, BigDecimal.valueOf(1E+13), UnitGroup.FORCE, R.string.dyne, R.string.dyne_short), - MyUnit(MyUnitIDS.joule_per_meter, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.joule_per_meter, R.string.joule_per_meter_short), - MyUnit(MyUnitIDS.joule_per_centimeter, BigDecimal.valueOf(1E+16), UnitGroup.FORCE, R.string.joule_per_centimeter, R.string.joule_per_centimeter_short), - MyUnit(MyUnitIDS.kilopound_force, BigDecimal.valueOf(4.448221615255E+21), UnitGroup.FORCE, R.string.kilopound_force, R.string.kilopound_force_short), - MyUnit(MyUnitIDS.pound_force, BigDecimal.valueOf(4.4482216152550001E18), UnitGroup.FORCE, R.string.pound_force, R.string.pound_force_short), MyUnit(MyUnitIDS.ounce_force, BigDecimal.valueOf(2.78013850953423008E17), UnitGroup.FORCE, R.string.ounce_force, R.string.ounce_force_short), + MyUnit(MyUnitIDS.pound_force, BigDecimal.valueOf(4.4482216152550001E18), UnitGroup.FORCE, R.string.pound_force, R.string.pound_force_short), + MyUnit(MyUnitIDS.kilopound_force, BigDecimal.valueOf(4.448221615255E+21), UnitGroup.FORCE, R.string.kilopound_force, R.string.kilopound_force_short), MyUnit(MyUnitIDS.pond, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.pond, R.string.pond_short), MyUnit(MyUnitIDS.kilopond, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilopond, R.string.kilopond_short), ) From f7cfd6563984c449a5ebc2811fc653db02a20706 Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Mon, 27 Mar 2023 14:49:55 +0300 Subject: [PATCH 12/12] Save Angle mode --- .../unitto/data/userprefs/UserPreferences.kt | 20 +++++++++- .../unitto/feature/calculator/AngleMode.kt | 21 ----------- .../feature/calculator/CalculatorScreen.kt | 2 +- .../feature/calculator/CalculatorUIState.kt | 2 +- .../feature/calculator/CalculatorViewModel.kt | 24 +++++------- .../components/CalculatorKeyboard.kt | 37 +++++++++---------- 6 files changed, 47 insertions(+), 59 deletions(-) delete mode 100644 feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/AngleMode.kt diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt index d8453d02..21ad7def 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt @@ -54,6 +54,7 @@ import javax.inject.Inject * @property shownUnitGroups [UnitGroup]s that user wants to see. Excludes other [UnitGroup]s, * @property enableVibrations When true will use haptic feedback in app. * @property enableToolsExperiment When true will enable experimental Tools screen. + * @property radianMode AngleMode in mxParser. When true - Radian, when False - Degree. */ data class UserPreferences( val themingMode: ThemingMode? = null, @@ -67,7 +68,8 @@ data class UserPreferences( val shownUnitGroups: List = ALL_UNIT_GROUPS, val enableVibrations: Boolean = true, val enableToolsExperiment: Boolean = false, - val startingScreen: String = TopLevelDestinations.Converter.route + val startingScreen: String = TopLevelDestinations.Converter.route, + val radianMode: Boolean = true ) /** @@ -90,6 +92,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS val ENABLE_VIBRATIONS = booleanPreferencesKey("ENABLE_VIBRATIONS_PREF_KEY") val ENABLE_TOOLS_EXPERIMENT = booleanPreferencesKey("ENABLE_TOOLS_EXPERIMENT_PREF_KEY") val STARTING_SCREEN = stringPreferencesKey("STARTING_SCREEN_PREF_KEY") + val RADIAN_MODE = booleanPreferencesKey("RADIAN_MODE_PREF_KEY") } val userPreferencesFlow: Flow = dataStore.data @@ -134,6 +137,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS val enableVibrations: Boolean = preferences[PrefsKeys.ENABLE_VIBRATIONS] ?: true val enableToolsExperiment: Boolean = preferences[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] ?: false val startingScreen: String = preferences[PrefsKeys.STARTING_SCREEN] ?: TopLevelDestinations.Converter.route + val radianMode: Boolean = preferences[PrefsKeys.RADIAN_MODE] ?: true UserPreferences( themingMode = themingMode, @@ -147,7 +151,8 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS shownUnitGroups = shownUnitGroups, enableVibrations = enableVibrations, enableToolsExperiment = enableToolsExperiment, - startingScreen = startingScreen + startingScreen = startingScreen, + radianMode = radianMode ) } @@ -269,4 +274,15 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS preferences[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] = enabled } } + + /** + * Update angle mode for calculator. + * + * @param radianMode When true - Radian, when False - Degree. + */ + suspend fun updateRadianMode(radianMode: Boolean) { + dataStore.edit { preferences -> + preferences[PrefsKeys.RADIAN_MODE] = radianMode + } + } } diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/AngleMode.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/AngleMode.kt deleted file mode 100644 index 67318a58..00000000 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/AngleMode.kt +++ /dev/null @@ -1,21 +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.feature.calculator - -internal enum class AngleMode { DEG, RAD } diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt index 01b8b82f..d45f567a 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt @@ -269,7 +269,7 @@ private fun CalculatorScreen( numPad = { CalculatorKeyboard( modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), - angleMode = uiState.angleMode, + radianMode = uiState.radianMode, allowVibration = uiState.allowVibration, addSymbol = addSymbol, clearSymbols = clearSymbols, diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt index 0db225fc..36f46269 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt @@ -24,7 +24,7 @@ import com.sadellie.unitto.data.model.HistoryItem internal data class CalculatorUIState( val input: TextFieldValue = TextFieldValue(), val output: String = "", - val angleMode: AngleMode = AngleMode.RAD, + val radianMode: Boolean = true, val history: List = emptyList(), val allowVibration: Boolean = false ) diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt index 955f37e0..5bcc7214 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt @@ -34,7 +34,6 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -46,7 +45,7 @@ import org.mariuszgromada.math.mxparser.mXparser as MathParser @HiltViewModel internal class CalculatorViewModel @Inject constructor( - userPrefsRepository: UserPreferencesRepository, + private val userPrefsRepository: UserPreferencesRepository, private val calculatorHistoryRepository: CalculatorHistoryRepository, private val textFieldController: TextFieldController ) : ViewModel() { @@ -58,16 +57,15 @@ internal class CalculatorViewModel @Inject constructor( ) private val _output: MutableStateFlow = MutableStateFlow("") - private val _angleMode: MutableStateFlow = MutableStateFlow(AngleMode.RAD) private val _history = calculatorHistoryRepository.historyFlow val uiState = combine( - textFieldController.input, _output, _angleMode, _history, _userPrefs - ) { input, output, angleMode, history, userPrefs -> + textFieldController.input, _output, _history, _userPrefs + ) { input, output, history, userPrefs -> return@combine CalculatorUIState( input = input, output = output, - angleMode = angleMode, + radianMode = userPrefs.radianMode, history = history, allowVibration = userPrefs.enableVibrations ) @@ -82,14 +80,8 @@ internal class CalculatorViewModel @Inject constructor( fun clearSymbols() = textFieldController.clearInput() fun toggleCalculatorMode() { - _angleMode.update { - if (it == AngleMode.DEG) { - MathParser.setRadiansMode() - AngleMode.RAD - } else { - MathParser.setDegreesMode() - AngleMode.DEG - } + viewModelScope.launch { + userPrefsRepository.updateRadianMode(!_userPrefs.value.radianMode) } } @@ -185,7 +177,9 @@ internal class CalculatorViewModel @Inject constructor( // Observe and invoke calculation without UI lag. viewModelScope.launch(Dispatchers.Default) { - merge(_userPrefs, textFieldController.input, _angleMode).collectLatest { + combine(_userPrefs, textFieldController.input) { userPrefs, _ -> + if (userPrefs.radianMode) MathParser.setRadiansMode() else MathParser.setDegreesMode() + }.collectLatest { calculateInput() } } diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt index 37af7526..54357868 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt @@ -93,12 +93,11 @@ import com.sadellie.unitto.core.ui.common.key.unittoicons.RightBracket import com.sadellie.unitto.core.ui.common.key.unittoicons.Sin import com.sadellie.unitto.core.ui.common.key.unittoicons.SquareRootWide import com.sadellie.unitto.core.ui.common.key.unittoicons.Tan -import com.sadellie.unitto.feature.calculator.AngleMode @Composable internal fun CalculatorKeyboard( modifier: Modifier, - angleMode: AngleMode, + radianMode: Boolean, allowVibration: Boolean, addSymbol: (String) -> Unit, clearSymbols: () -> Unit, @@ -109,7 +108,7 @@ internal fun CalculatorKeyboard( if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) { PortraitKeyboard( modifier = modifier, - angleMode = angleMode, + radianMode = radianMode, allowVibration = allowVibration, addSymbol = addSymbol, toggleAngleMode = toggleAngleMode, @@ -120,7 +119,7 @@ internal fun CalculatorKeyboard( } else { LandscapeKeyboard( modifier = modifier, - angleMode = angleMode, + radianMode = radianMode, allowVibration = allowVibration, addSymbol = addSymbol, toggleAngleMode = toggleAngleMode, @@ -134,7 +133,7 @@ internal fun CalculatorKeyboard( @Composable private fun PortraitKeyboard( modifier: Modifier, - angleMode: AngleMode, + radianMode: Boolean, allowVibration: Boolean, addSymbol: (String) -> Unit, toggleAngleMode: () -> Unit, @@ -175,7 +174,7 @@ private fun PortraitKeyboard( allowVibration = allowVibration, addSymbol = addSymbol, showAdditional = showAdditional, - angleMode = angleMode, + radianMode = radianMode, toggleAngleMode = toggleAngleMode, toggleInvMode = { invMode = !invMode } ) @@ -185,7 +184,7 @@ private fun PortraitKeyboard( allowVibration = allowVibration, addSymbol = addSymbol, showAdditional = showAdditional, - angleMode = angleMode, + radianMode = radianMode, toggleAngleMode = toggleAngleMode, toggleInvMode = { invMode = !invMode } ) @@ -241,7 +240,7 @@ private fun AdditionalButtonsPortrait( allowVibration: Boolean, addSymbol: (String) -> Unit, showAdditional: Boolean, - angleMode: AngleMode, + radianMode: Boolean, toggleAngleMode: () -> Unit, toggleInvMode: () -> Unit ) { @@ -255,7 +254,7 @@ private fun AdditionalButtonsPortrait( AnimatedVisibility(showAdditional) { Column { Row(horizontalArrangement = Arrangement.spacedBy(2.dp)) { - KeyboardButtonAdditional(modifier, if (angleMode == AngleMode.DEG) UnittoIcons.Deg else UnittoIcons.Rad, allowVibration) { toggleAngleMode() } + KeyboardButtonAdditional(modifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } KeyboardButtonAdditional(modifier, UnittoIcons.Sin, allowVibration) { addSymbol(Token.sin) } KeyboardButtonAdditional(modifier, UnittoIcons.Cos, allowVibration) { addSymbol(Token.cos) } KeyboardButtonAdditional(modifier, UnittoIcons.Tan, allowVibration) { addSymbol(Token.tan) } @@ -277,7 +276,7 @@ private fun AdditionalButtonsPortraitInverse( allowVibration: Boolean, addSymbol: (String) -> Unit, showAdditional: Boolean, - angleMode: AngleMode, + radianMode: Boolean, toggleAngleMode: () -> Unit, toggleInvMode: () -> Unit ) { @@ -291,7 +290,7 @@ private fun AdditionalButtonsPortraitInverse( AnimatedVisibility(showAdditional) { Column { Row(horizontalArrangement = Arrangement.spacedBy(2.dp)) { - KeyboardButtonAdditional(modifier, if (angleMode == AngleMode.DEG) UnittoIcons.Deg else UnittoIcons.Rad, allowVibration) { toggleAngleMode() } + KeyboardButtonAdditional(modifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } KeyboardButtonAdditional(modifier, UnittoIcons.ArSin, allowVibration) { addSymbol(Token.arSin) } KeyboardButtonAdditional(modifier, UnittoIcons.ArCos, allowVibration) { addSymbol(Token.arCos) } KeyboardButtonAdditional(modifier, UnittoIcons.AcTan, allowVibration) { addSymbol(Token.acTan) } @@ -310,7 +309,7 @@ private fun AdditionalButtonsPortraitInverse( @Composable private fun LandscapeKeyboard( modifier: Modifier, - angleMode: AngleMode, + radianMode: Boolean, allowVibration: Boolean, addSymbol: (String) -> Unit, toggleAngleMode: () -> Unit, @@ -334,7 +333,7 @@ private fun LandscapeKeyboard( modifier = Modifier.weight(1f), buttonModifier = buttonModifier, allowVibration = allowVibration, - angleMode = angleMode, + radianMode = radianMode, addSymbol = addSymbol, toggleAngleMode = toggleAngleMode, toggleInvMode = { invMode = !invMode } @@ -344,7 +343,7 @@ private fun LandscapeKeyboard( modifier = Modifier.weight(1f), buttonModifier = buttonModifier, allowVibration = allowVibration, - angleMode = angleMode, + radianMode = radianMode, addSymbol = addSymbol, toggleAngleMode = toggleAngleMode, toggleInvMode = { invMode = !invMode } @@ -392,13 +391,13 @@ private fun AdditionalButtonsLandscape( modifier: Modifier, buttonModifier: Modifier, allowVibration: Boolean, - angleMode: AngleMode, + radianMode: Boolean, addSymbol: (String) -> Unit, toggleAngleMode: () -> Unit, toggleInvMode: () -> Unit ) { Column(modifier) { - KeyboardButtonAdditional(buttonModifier, if (angleMode == AngleMode.DEG) UnittoIcons.Deg else UnittoIcons.Rad, allowVibration) { toggleAngleMode() } + KeyboardButtonAdditional(buttonModifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration) { toggleInvMode() } KeyboardButtonAdditional(buttonModifier, UnittoIcons.Sin, allowVibration) { addSymbol(Token.sin) } KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration) { addSymbol(Token.e) } @@ -424,13 +423,13 @@ private fun AdditionalButtonsLandscapeInverse( modifier: Modifier, buttonModifier: Modifier, allowVibration: Boolean, - angleMode: AngleMode, + radianMode: Boolean, addSymbol: (String) -> Unit, toggleAngleMode: () -> Unit, toggleInvMode: () -> Unit ) { Column(modifier) { - KeyboardButtonAdditional(buttonModifier, if (angleMode == AngleMode.DEG) UnittoIcons.Deg else UnittoIcons.Rad, allowVibration) { toggleAngleMode() } + KeyboardButtonAdditional(buttonModifier, if (radianMode) UnittoIcons.Rad else UnittoIcons.Deg, allowVibration) { toggleAngleMode() } KeyboardButtonAdditional(buttonModifier, UnittoIcons.Inv, allowVibration) { toggleInvMode() } KeyboardButtonAdditional(buttonModifier, UnittoIcons.ArSin, allowVibration) { addSymbol(Token.arSin) } KeyboardButtonAdditional(buttonModifier, UnittoIcons.E, allowVibration) { addSymbol(Token.e) } @@ -456,7 +455,7 @@ private fun AdditionalButtonsLandscapeInverse( private fun PreviewCalculatorKeyboard() { CalculatorKeyboard( modifier = Modifier, - angleMode = AngleMode.DEG, + radianMode = true, addSymbol = {}, clearSymbols = {}, deleteSymbol = {},