Compare commits

...

13 Commits

Author SHA1 Message Date
145179bba3 Update dependencies 2022-12-18 04:39:01 -06:00
Jakub Kalinowski
c7d1e92cae Issue 1589: Fixed crash after choosing Settings/Rate app when there's no Play Store on the device (#1590)
* Using startActivitySafely when launching Play Store

* Returning true for rateApp click
2022-12-12 00:55:58 +01:00
dependabot[bot]
d24dcbf2ca Bump kotlinVersion from 1.7.10 to 1.7.21
Bumps `kotlinVersion` from 1.7.10 to 1.7.21.

Updates `org.jetbrains.kotlin.android` from 1.7.10 to 1.7.21

Updates `org.jetbrains.kotlin.kapt` from 1.7.10 to 1.7.21

Updates `org.jetbrains.kotlin.android.extensions` from 1.7.10 to 1.7.21

Updates `org.jetbrains.kotlin.multiplatform` from 1.7.10 to 1.7.21

Updates `kotlin-stdlib-jdk8` from 1.7.10 to 1.7.21
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.10...v1.7.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin.android
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.jetbrains.kotlin.kapt
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.jetbrains.kotlin.android.extensions
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.jetbrains.kotlin.multiplatform
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-26 22:12:04 +01:00
dependabot[bot]
579b33cc78 Bump appcompat from 1.5.0 to 1.5.1
Bumps appcompat from 1.5.0 to 1.5.1.

---
updated-dependencies:
- dependency-name: androidx.appcompat:appcompat
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-25 22:12:00 +01:00
dependabot[bot]
1a3e6315a1 Bump opencsv from 5.6 to 5.7.1
Bumps opencsv from 5.6 to 5.7.1.

---
updated-dependencies:
- dependency-name: com.opencsv:opencsv
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-25 17:29:07 +01:00
dependabot[bot]
7f4d06d15d Bump logback-classic from 1.4.0 to 1.4.4
Bumps [logback-classic](https://github.com/qos-ch/logback) from 1.4.0 to 1.4.4.
- [Release notes](https://github.com/qos-ch/logback/releases)
- [Commits](https://github.com/qos-ch/logback/compare/v_1.4.0...v_1.4.4)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-25 17:28:46 +01:00
dependabot[bot]
b8033a6012 Bump sqlite-jdbc from 3.39.2.1 to 3.39.3.0
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.39.2.1 to 3.39.3.0.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.39.2.1...3.39.3.0)

---
updated-dependencies:
- dependency-name: org.xerial:sqlite-jdbc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-25 17:28:36 +01:00
404671546c Revert "uhabits-core: Add js targets"
This reverts commit da09df2dd1.
2022-09-24 20:39:54 -05:00
a94c6e8b9f Merge branch 'master' into dev 2022-09-24 19:44:31 -05:00
da09df2dd1 uhabits-core: Add js targets 2022-09-24 19:42:09 -05:00
40a4d254f5 Merge branch 'hotfix/2.1.1' 2022-09-24 19:40:04 -05:00
177d01edd9 Fix Tasker plugin; bump version to 2.1.1
Fixes #1503
2022-09-24 19:25:42 -05:00
9f5da7b4fe Update TEST.md
[skip ci]
2022-09-10 20:44:00 -05:00
10 changed files with 62 additions and 72 deletions

View File

@@ -1,5 +1,9 @@
# Changelog
## [2.1.1] -- 2022-09-24
### Fixed
- Fix Tasker plugin (@iSoron, #1503)
## [2.1.0] -- 2022-09-10
### Added
- Allow user to add notes to specific dates (@vbh, #1103)

View File

@@ -1,6 +1,6 @@
plugins {
val kotlinVersion = "1.7.10"
id("com.android.application") version ("7.3.0-rc01") apply (false)
val kotlinVersion = "1.7.21"
id("com.android.application") version ("7.3.1") apply (false)
id("org.jetbrains.kotlin.android") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false)
id("org.jetbrains.kotlin.android.extensions") version kotlinVersion apply (false)

View File

@@ -2,51 +2,25 @@
Loop Habit Tracker has a fairly large number of automated tests to reduce the chance of bugs being silently introduced in our code base. The tests are divided into three categories:
* **Small tests:** These tests run very quickly on the developer's computer, inside a JVM, and do not need an Android emulator or device. They typically test the correctness of core functions of the application, such as the computation of scores and streaks.
* **Medium tests:** These tests require an Android emulator or device, but they are still quite fast to run, since only individual classes are tested. The app itself does not need to be launched. Examples include *view tests*, which render our custom views on the device and compare them against prerendered images.
* **Large tests:** These are end-to-end tests, which launch the application on an Android emulator and interact with it by touching the screen, much like a regular user.
- **Unit tests:** These tests run very quickly on the developer's computer, inside a JVM, and do not need an Android emulator or device. They typically test the correctness of core functions of the application, such as the computation of scores and streaks.
- **Instrumented tests:** These tests require an Android emulator or device. _Medium_ instrumented tests are still quite fast to run, since only individual classes are tested. The app itself does not need to be launched. Examples include _view tests_, which render our custom views on the device and compare them against prerendered images. _Large_ instrumented tests launch the application on an Android emulator and interact with it by touching the screen, much like a regular user.
## Running small tests
## Running unit tests
Small tests can be launched by running `./gradlew test` or by right-clicking a particular class/method in Android Studio and selecting "Run testMethod()" or "Run ClassTest". An alternative way is to use `build.sh`, the script used by our continuous integration server. By running `./build.sh build`, the script will automatically build and run all small tests.
Unit tests can be launched by running `./gradlew test` or by right-clicking a particular class/method in Android Studio and selecting "Run testMethod()" or "Run ClassTest". An alternative way is to use `build.sh`, the script used by our continuous integration server. By running `./build.sh build`, the script will automatically build and run all small tests.
## Running medium tests
## Running instrumented tests
To run medium tests, it is recommended to use the `build.sh` script:
To run medium tests, it is recommended to use the `build.sh` script.
./build.sh build
./build.sh medium-tests
1. Run `./build.sh android-setup API` to create the emulator, where `API` is the desired API level.
2. Run `./build.sh android-tests API` to run the tests on a single API.
3. Run `./build.sh android-tests-parallel API API...` to run the tests on multiple APIs in parallel.
Note that instrumented tests are designed to run on a clean install, inside an emulator. They will not work on actual devices. All tests are also designed for a particular screen size, namely the Nexus 4 configuration (4.7" 768x1280 xhdpi), and a particular locale, namely English (US). Furthermore:
For this script to succeed, make sure that an emulator is currently running, or that a device (with developer mode activated) is connected via USB.
- No additional apps should be installed on the device;
- The homescreen must look exactly like it was when the emulator was originally created, with no additional icons or widgets;
- All animations must be manually disabled.
**WARNING!** This script will uninstall the app prior to testing it, and therefore delete all user data!
If there are failing view tests (that is, if some custom views do not render exactly like the prerendered images we have), then the script `./build.sh fetch-images` can be used to download both the actual and the expected images from the device. The images will be downloaded from the device into the folder `tmp/`. After verifying the differences, if you feel that the actual images are actually fine and should replace the prerendered ones, then run `./build.sh accept-images`.
## Running large tests
Large tests are significantly more complicated to run. In particular, they require:
* An Android emulator; they will **not** work on actual devices;
* A vanilla x86 AOSP image; they will **not** work with Google API images;
* A particular screen size, namely the Nexus 4 configuration on Android Studio (4.7 768x1280 xhdpi);
* A particular locale, namely English (US).
Furthermore:
* No additional apps should be installed on the device;
* The homescreen must look exactly like it was when the emulator was originally created, with no additional icons or widgets;
* Developer mode must be activated, and all animations must be manually disabled.
Only the following Android versions are supported by our test suite:
* Android 7.0 (API 24)
* Android 7.1.1 (API 25)
* Android 8.0 (API 26)
* Android 8.1 (API 27)
* Android 9.0 (API 28)
* Android 10.0 (API 29)
After creating an emulator and configuring it exactly as described above, launch it, wait for it to finish booting up, then run `./build.sh large-tests`. As mentioned before, this script will uninstall the app before testing it, and therefore will delete all the user data.
If there are failing view tests (that is, if some custom views do not render exactly like the prerendered images we have), then both the actual and expected images will be automatically downloaded from the device to the folder `uhabits-android/build/outputs`. After verifying the differences, if you feel that the actual images are actually fine and should replace the prerendered ones, then run `./build.sh android-accept-images`.

View File

@@ -35,8 +35,8 @@ android {
compileSdk = 32
defaultConfig {
versionCode = 20100
versionName = "2.1.0"
versionCode = 20101
versionName = "2.1.1"
minSdk = 28
targetSdk = 31
applicationId = "org.isoron.uhabits"
@@ -81,7 +81,7 @@ android {
dependencies {
val daggerVersion = "2.43.2"
val kotlinVersion = "1.7.10"
val kotlinVersion = "1.7.21"
val kxCoroutinesVersion = "1.6.4"
val ktorVersion = "1.6.8"
val espressoVersion = "3.4.0"
@@ -92,10 +92,10 @@ dependencies {
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:2.28.3")
androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion")
androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion")
androidTestImplementation("androidx.annotation:annotation:1.4.0")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.annotation:annotation:1.5.0")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
androidTestImplementation("androidx.test:rules:1.4.0")
androidTestImplementation("androidx.test:rules:1.5.0")
androidTestImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
compileOnly("javax.annotation:jsr250-api:1.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2")
@@ -110,11 +110,11 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kxCoroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kxCoroutinesVersion")
implementation("androidx.appcompat:appcompat:1.5.0")
implementation("androidx.appcompat:appcompat:1.5.1")
implementation("androidx.legacy:legacy-preference-v14:1.0.0")
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation("com.google.android.material:material:1.6.1")
implementation("com.opencsv:opencsv:5.6")
implementation("com.google.android.material:material:1.7.0")
implementation("com.opencsv:opencsv:5.7.1")
implementation(project(":uhabits-core"))
kapt("com.google.dagger:dagger-compiler:$daggerVersion")
kaptAndroidTest("com.google.dagger:dagger-compiler:$daggerVersion")

View File

@@ -270,7 +270,7 @@
<!-- Locale/Tasker -->
<receiver
android:name=".automation.FireSettingReceiver"
android:exported="false">
android:exported="true">
<intent-filter>
<action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" />
</intent-filter>

View File

@@ -22,6 +22,7 @@ import android.app.backup.BackupManager
import android.content.Intent
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.util.Log
@@ -43,6 +44,7 @@ import org.isoron.uhabits.core.utils.DateUtils.Companion.getLongWeekdayNames
import org.isoron.uhabits.notifications.AndroidNotificationTray.Companion.createAndroidNotificationChannel
import org.isoron.uhabits.notifications.RingtoneManager
import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.startActivitySafely
import org.isoron.uhabits.widgets.WidgetUpdater
import java.util.Calendar
@@ -92,16 +94,24 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
override fun onPreferenceTreeClick(preference: Preference): Boolean {
val key = preference.key ?: return false
if (key == "reminderSound") {
showRingtonePicker()
return true
} else if (key == "reminderCustomize") {
createAndroidNotificationChannel(requireContext())
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
startActivity(intent)
return true
when (key) {
"reminderSound" -> {
showRingtonePicker()
return true
}
"reminderCustomize" -> {
createAndroidNotificationChannel(requireContext())
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
startActivity(intent)
return true
}
"rateApp" -> {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.playStoreURL)))
activity?.startActivitySafely(intent)
return true
}
}
return super.onPreferenceTreeClick(preference)
}

View File

@@ -1,6 +1,10 @@
2.1.1:
* Fix Tasker plugin
2.1:
* Add notes to specific dates
* Track at-most measurable habits
* Add skips to measurable habits
* Bring back custom frequencies
* Other minor improvements and bug fixes
* Other minor improvements and bug fixes

View File

@@ -160,11 +160,9 @@
</Preference>
<Preference
android:key="rateApp"
android:title="@string/pref_rate_this_app"
app:iconSpaceReserved="false">
<intent
android:action="android.intent.action.VIEW"
android:data="@string/playStoreURL" />
</Preference>
<Preference

View File

@@ -45,11 +45,11 @@ kotlin {
implementation(kotlin("stdlib-jdk8"))
compileOnly("com.google.dagger:dagger:2.43.2")
implementation("com.google.guava:guava:31.1-android")
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.7.10")
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.7.21")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4")
implementation("androidx.annotation:annotation:1.4.0")
implementation("androidx.annotation:annotation:1.5.0")
implementation("com.google.code.findbugs:jsr305:3.0.2")
implementation("com.opencsv:opencsv:5.6")
implementation("com.opencsv:opencsv:5.7.1")
implementation("commons-codec:commons-codec:1.15")
implementation("org.apache.commons:commons-lang3:3.12.0")
}
@@ -59,7 +59,7 @@ kotlin {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
implementation("org.xerial:sqlite-jdbc:3.39.2.1")
implementation("org.xerial:sqlite-jdbc:3.40.0.0")
implementation("org.hamcrest:hamcrest:2.2")
implementation("org.apache.commons:commons-io:1.3.2")
implementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")

View File

@@ -34,8 +34,8 @@ application {
dependencies {
val ktorVersion = "1.6.8"
val kotlinVersion = "1.7.10"
val logbackVersion = "1.4.0"
val kotlinVersion = "1.7.21"
val logbackVersion = "1.4.4"
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
implementation("io.ktor:ktor-server-netty:$ktorVersion")
implementation("ch.qos.logback:logback-classic:$logbackVersion")