Merge branch 'dev' into feature/sync
55
.github/workflows/main.yml
vendored
@@ -1,31 +1,50 @@
|
|||||||
name: Build & Test
|
name: Build & Test
|
||||||
|
on: [push, pull_request]
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- dev
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- dev
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: macOS-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- name: Check out source code
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
- name: Install Java Development Kit 1.8
|
- name: Install Java Development Kit 1.8
|
||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: 1.8
|
||||||
|
|
||||||
- name: Build APK & Run small tests
|
- name: Build APK & Run small tests
|
||||||
run: android/build.sh build
|
run: android/build.sh build
|
||||||
|
|
||||||
|
- name: Upload APK
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: debug-apk
|
||||||
|
path: android/build/*apk
|
||||||
|
|
||||||
|
- name: Upload build folder
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: build
|
||||||
|
path: android/uhabits-android/build/
|
||||||
|
|
||||||
|
test:
|
||||||
|
needs: build
|
||||||
|
runs-on: macOS-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
api-level: [23, 24, 25, 26, 27, 28, 29]
|
||||||
|
steps:
|
||||||
|
- name: Check out source code
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Download previous build folder
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
name: build
|
||||||
|
path: android/uhabits-android/build/
|
||||||
|
|
||||||
- name: Run medium tests
|
- name: Run medium tests
|
||||||
uses: ReactiveCircus/android-emulator-runner@v2.2.0
|
uses: ReactiveCircus/android-emulator-runner@v2
|
||||||
with:
|
with:
|
||||||
api-level: 29
|
api-level: ${{ matrix.api-level }}
|
||||||
script: android/build.sh medium-tests
|
script: android/build.sh medium-tests
|
||||||
- name: Upload artifacts
|
|
||||||
uses: actions/upload-artifact@v1
|
|
||||||
with:
|
|
||||||
name: Build
|
|
||||||
path: android/uhabits-android/build/outputs/
|
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
<a href="https://github.com/iSoron/uhabits/actions?query=workflow%3A%22Build+%26+Test%22">
|
||||||
|
<img src="https://github.com/iSoron/uhabits/workflows/Build%20&%20Test/badge.svg" />
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/iSoron/uhabits/releases">
|
||||||
|
<img src="https://img.shields.io/github/v/release/iSoron/uhabits" />
|
||||||
|
</a>
|
||||||
|
|
||||||
# Loop Habit Tracker
|
# Loop Habit Tracker
|
||||||
|
|
||||||
Loop is a mobile app that helps you create and maintain good habits,
|
Loop is a mobile app that helps you create and maintain good habits,
|
||||||
|
|||||||
@@ -232,7 +232,10 @@ case "$1" in
|
|||||||
|
|
||||||
medium-tests)
|
medium-tests)
|
||||||
shift; parse_opts $*
|
shift; parse_opts $*
|
||||||
run_tests medium
|
for attempt in {1..3}; do
|
||||||
|
(run_tests medium) && exit 0
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
large-tests)
|
large-tests)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
VERSION_CODE = 20000
|
VERSION_CODE = 20000
|
||||||
VERSION_NAME = 2.0.0
|
VERSION_NAME = 2.0.0
|
||||||
|
|
||||||
MIN_SDK_VERSION = 21
|
MIN_SDK_VERSION = 23
|
||||||
TARGET_SDK_VERSION = 29
|
TARGET_SDK_VERSION = 29
|
||||||
COMPILE_SDK_VERSION = 29
|
COMPILE_SDK_VERSION = 29
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
coreLibraryDesugaringEnabled true
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
@@ -102,6 +103,8 @@ dependencies {
|
|||||||
implementation "io.ktor:ktor-client-jackson:$KTOR_VERSION"
|
implementation "io.ktor:ktor-client-jackson:$KTOR_VERSION"
|
||||||
implementation "com.google.guava:guava:30.0-android"
|
implementation "com.google.guava:guava:30.0-android"
|
||||||
|
|
||||||
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
|
||||||
|
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
compileOnly "javax.annotation:jsr250-api:1.0"
|
compileOnly "javax.annotation:jsr250-api:1.0"
|
||||||
compileOnly "com.google.auto.factory:auto-factory:$AUTO_FACTORY_VERSION"
|
compileOnly "com.google.auto.factory:auto-factory:$AUTO_FACTORY_VERSION"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 585 B After Width: | Height: | Size: 585 B |
|
Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 545 B |
|
Before Width: | Height: | Size: 583 B After Width: | Height: | Size: 583 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -230,9 +230,9 @@ public class BaseAndroidTest extends TestCase
|
|||||||
int minute) throws Exception
|
int minute) throws Exception
|
||||||
{
|
{
|
||||||
GregorianCalendar cal = new GregorianCalendar();
|
GregorianCalendar cal = new GregorianCalendar();
|
||||||
cal.setTimeZone(TimeZone.getTimeZone(tz));
|
|
||||||
cal.set(Calendar.SECOND, 0);
|
cal.set(Calendar.SECOND, 0);
|
||||||
cal.set(year, javaMonth, day, hourOfDay, minute);
|
cal.set(year, javaMonth, day, hourOfDay, minute);
|
||||||
|
cal.setTimeZone(TimeZone.getTimeZone(tz));
|
||||||
setSystemTime(cal);
|
setSystemTime(cal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +249,22 @@ public class BaseAndroidTest extends TestCase
|
|||||||
device.executeShellCommand(command);
|
device.executeShellCommand(command);
|
||||||
|
|
||||||
// Set time
|
// Set time
|
||||||
|
String date = String.format("%02d%02d%02d%02d%02d.%02d",
|
||||||
|
cal.get(Calendar.MONTH) + 1,
|
||||||
|
cal.get(Calendar.DAY_OF_MONTH),
|
||||||
|
cal.get(Calendar.HOUR_OF_DAY),
|
||||||
|
cal.get(Calendar.MINUTE),
|
||||||
|
cal.get(Calendar.YEAR),
|
||||||
|
cal.get(Calendar.SECOND));
|
||||||
|
|
||||||
|
// Set time (method 1)
|
||||||
|
// Run twice to override daylight saving time
|
||||||
|
device.executeShellCommand("date " + date);
|
||||||
|
device.executeShellCommand("date " + date);
|
||||||
|
|
||||||
|
// Set time (method 2)
|
||||||
|
// Run in addition to the method above because one of these mail fail, depending
|
||||||
|
// on the Android API version.
|
||||||
command = String.format("date -u @%d", cal.getTimeInMillis() / 1000);
|
command = String.format("date -u @%d", cal.getTimeInMillis() / 1000);
|
||||||
device.executeShellCommand(command);
|
device.executeShellCommand(command);
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ import org.isoron.uhabits.widgets.*;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static android.os.Build.VERSION.*;
|
|
||||||
import static android.os.Build.VERSION_CODES.*;
|
|
||||||
import static android.view.View.MeasureSpec.*;
|
import static android.view.View.MeasureSpec.*;
|
||||||
|
|
||||||
public class BaseViewTest extends BaseAndroidTest
|
public class BaseViewTest extends BaseAndroidTest
|
||||||
@@ -51,7 +49,7 @@ public class BaseViewTest extends BaseAndroidTest
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
|
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
|
||||||
expectedImagePath = getVersionedPath(expectedImagePath);
|
expectedImagePath = "views/" + expectedImagePath;
|
||||||
Bitmap actual = renderView(view);
|
Bitmap actual = renderView(view);
|
||||||
if(actual == null) throw new IllegalStateException("actual is null");
|
if(actual == null) throw new IllegalStateException("actual is null");
|
||||||
|
|
||||||
@@ -158,16 +156,6 @@ public class BaseViewTest extends BaseAndroidTest
|
|||||||
return BitmapFactory.decodeStream(stream);
|
return BitmapFactory.decodeStream(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getVersionedPath(String path)
|
|
||||||
{
|
|
||||||
int version = SDK_INT;
|
|
||||||
if (version >= 26) version = 26;
|
|
||||||
else if (version >= LOLLIPOP) version = LOLLIPOP;
|
|
||||||
else if (version >= KITKAT) version = KITKAT;
|
|
||||||
|
|
||||||
return String.format("views-v%d/%s", version, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String saveBitmap(String filename, String suffix, Bitmap bitmap)
|
private String saveBitmap(String filename, String suffix, Bitmap bitmap)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
|||||||
12
docs/TEST.md
@@ -42,11 +42,11 @@ Furthermore:
|
|||||||
|
|
||||||
Only the following Android versions are supported by our test suite:
|
Only the following Android versions are supported by our test suite:
|
||||||
|
|
||||||
* Android 5.0 (Lollipop)
|
* Android 7.0 (API 24)
|
||||||
* Android 6.0 (Marshmallow)
|
* Android 7.1.1 (API 25)
|
||||||
* Android 7.1.1 (Nougat)
|
* Android 8.0 (API 26)
|
||||||
* Android 8.1 (Oreo)
|
* Android 8.1 (API 27)
|
||||||
* Android 9.0 (Pie)
|
* Android 9.0 (API 28)
|
||||||
* Android 10.0
|
* Android 10.0 (API 30)
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||