Merge branch 'hotfix/1.8.8'

pull/605/head v1.8.8
Alinson S. Xavier 5 years ago
commit 0cce6b30b1

1
.gitignore vendored

@ -5,6 +5,7 @@
*.swp
*~.nib
.DS_Store
._.DS_Store
.externalNativeBuild
.gradle
.idea

@ -1,5 +1,10 @@
# Changelog
### 1.8.8 (June 21, 2020)
* Make small changes to the habit scheduling algorithm, so that "1 time every x days" habits work more predictably.
* Fix crash when saving habit
### 1.8.0 (Jan 1, 2020)
* New bar chart showing number of repetitions performed in each week, month, quarter or year.

@ -50,10 +50,6 @@ log_info() {
}
fail() {
if [ ! -z ${AVD_NAME} ]; then
stop_emulator
stop_gradle_daemon
fi
log_error "BUILD FAILED"
exit 1
}
@ -64,22 +60,6 @@ if [ ! -z $RELEASE ]; then
fi
start_emulator() {
log_info "Starting emulator ($AVD_NAME)"
$EMULATOR -avd ${AVD_NAME} -port ${AVD_SERIAL} -no-audio -no-window &
$ADB wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done; input keyevent 82'
}
stop_emulator() {
log_info "Stopping emulator"
$ADB emu kill
}
stop_gradle_daemon() {
log_info "Stopping gradle daemon"
$GRADLE --stop
}
run_adb_as_root() {
log_info "Running adb as root"
$ADB root
@ -113,12 +93,6 @@ build_instrumentation_apk() {
fi
}
clean_output_dir() {
log_info "Cleaning output directory"
rm -rf ${OUTPUTS_DIR}
mkdir -p ${OUTPUTS_DIR}
}
uninstall_apk() {
log_info "Uninstalling existing APK"
$ADB uninstall ${PACKAGE_NAME}
@ -152,10 +126,10 @@ run_instrumented_tests() {
log_info "Running instrumented tests"
$ADB shell am instrument \
-r -e coverage true -e size $SIZE \
-w ${PACKAGE_NAME}.test/android.support.test.runner.AndroidJUnitRunner \
-w ${PACKAGE_NAME}.test/androidx.test.runner.AndroidJUnitRunner \
| tee ${OUTPUTS_DIR}/instrument.txt
if grep FAILURES $OUTPUTS_DIR/instrument.txt; then
if grep "\(INSTRUMENTATION_STATUS_CODE.*-1\|FAILURES\)" $OUTPUTS_DIR/instrument.txt; then
log_error "Some instrumented tests failed"
fetch_images
fetch_logcat
@ -207,8 +181,8 @@ fetch_images() {
}
accept_images() {
find tmp/test-screenshots -name '*.expected*' -delete
rsync -av tmp/test-screenshots/ uhabits-android/src/androidTest/assets/
find $OUTPUTS_DIR/test-screenshots -name '*.expected*' -delete
rsync -av $OUTPUTS_DIR/test-screenshots/ uhabits-android/src/androidTest/assets/
}
run_tests() {
@ -225,19 +199,26 @@ run_tests() {
}
parse_opts() {
OPTS=`getopt -o ur --long uninstall-first,release -n 'build.sh' -- "$@"`
OPTS=`getopt -o r --long release -n 'build.sh' -- "$@"`
if [ $? != 0 ] ; then exit 1; fi
eval set -- "$OPTS"
while true; do
case "$1" in
-u | --uninstall-first ) UNINSTALL_FIRST=1; shift ;;
-r | --release ) RELEASE=1; shift ;;
* ) break ;;
esac
done
}
remove_build_dir() {
rm -rfv build
rm -rfv android-base/build
rm -rfv android-pickers/build
rm -rfv uhabits-android/build
rm -rfv uhabits-core/build
}
case "$1" in
build)
shift; parse_opts $*
@ -248,33 +229,6 @@ case "$1" in
#generate_coverage_badge
;;
ci-tests)
if [ -z $3 ]; then
cat <<- END
Usage: $0 ci-tests AVD_NAME AVD_SERIAL [options]
Parameters:
AVD_NAME name of the virtual android device to start
AVD_SERIAL adb port to use (e.g. 5560)
Options:
-u --uninstall-first Uninstall existing APK first
-r --release Test release APK, instead of debug
END
exit 1
fi
shift; AVD_NAME=$1
shift; AVD_SERIAL=$1
shift; parse_opts $*
ADB="${ADB} -s emulator-${AVD_SERIAL}"
start_emulator
run_tests medium
stop_emulator
stop_gradle_daemon
;;
medium-tests)
shift; parse_opts $*
run_tests medium
@ -299,20 +253,27 @@ case "$1" in
install_apk
;;
clean)
remove_build_dir
;;
*)
cat <<- END
cat <<END
Usage: $0 <command> [options]
Builds, installs and tests Loop Habit Tracker
Commands:
ci-tests Start emulator silently, run tests then kill emulator
local-tests Run all tests on connected device
install Install app on connected device
fetch-images Fetches failed view test images from device
accept-images Copies fetched images to corresponding assets folder
build Build APK and run JVM tests
clean Remove build directory
fetch-images Fetches failed view test images from device
install Install app on connected device
large-tests Run large-sized tests on connected device
medium-tests Run medium-sized tests on connected device
Options:
-r --release Build and test release APK, instead of debug
END
exit 1
;;
esac

@ -1,5 +1,5 @@
VERSION_CODE = 50
VERSION_NAME = 1.8.7
VERSION_CODE = 51
VERSION_NAME = 1.8.8
MIN_SDK_VERSION = 21
TARGET_SDK_VERSION = 29

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

@ -1,61 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class ExportCSVTaskTest extends BaseAndroidTest
{
@Before
@Override
public void setUp()
{
super.setUp();
}
// @Test
// public void testExportCSV() throws Throwable
// {
// fixtures.purgeHabits(habitList);
// fixtures.createShortHabit();
//
// List<Habit> selected = new LinkedList<>();
// for (Habit h : habitList) selected.add(h);
// File outputDir = new AndroidDirFinder(targetContext).getFilesDir("CSV");
// assertNotNull(outputDir);
//
// taskRunner.execute(
// new ExportCSVTask(habitList, selected, outputDir, archiveFilename -> {
// assertThat(archiveFilename, is(not(nullValue())));
// File f = new File(archiveFilename);
// assertTrue(f.exists());
// assertTrue(f.canRead());
// }));
// }
}

@ -1,57 +0,0 @@
/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.tasks;
import androidx.test.filters.*;
import androidx.test.runner.*;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.isoron.uhabits.*;
import org.junit.*;
import org.junit.runner.*;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class ExportDBTaskTest extends BaseAndroidTest
{
@Override
@Before
public void setUp()
{
super.setUp();
}
// @Test
// public void testExportCSV() throws Throwable
// {
// ExportDBTask task =
// new ExportDBTask(targetContext, new AndroidDirFinder(targetContext),
// filename ->
// {
// assertNotNull(filename);
// File f = new File(filename);
// assertTrue(f.exists());
// assertTrue(f.canRead());
// });
//
// taskRunner.execute(task);
// }
}

@ -57,7 +57,13 @@ public class TargetPanel extends FrameLayout
public double getTargetValue()
{
String sValue = tvTargetValue.getText().toString();
return Double.parseDouble(sValue);
double value = 0;
try {
value = Double.parseDouble(sValue);
} catch (NumberFormatException e) {
// NOP
}
return value;
}
public void setTargetValue(double targetValue)

@ -1,11 +1,12 @@
1.8.7
* Fix notification issues
1.8.8
* Small tweaks to the habit scheduling algorithm
* Fix some crashes
1.8:
* New bar chart showing number of repetitions performed each week, month or year
* Performing habits on irregular weekdays will no longer break your streak
* More colors to choose from (now 20 in total)
* Ability to customize how transparent the widgets are
* Ability to customize the first day of the week
* Yes/No buttons on notifications instead of just "Check"
* Customize how transparent the widgets are
* Customize the first day of the week
* Yes/No buttons on notifications
* Automatic dark theme (Android 10)
* Smaller APK and backup files

@ -122,22 +122,28 @@ public abstract class CheckmarkList
}
/**
* Starting from the oldest interval, this function tries to slide the
* Starting from the second newest interval, this function tries to slide the
* intervals backwards into the past, so that gaps are eliminated and
* streaks are maximized. When it detects that sliding an interval
* would not help fixing any gap, it leaves the interval unchanged.
* streaks are maximized.
*/
static void snapIntervalsTogether(@NonNull ArrayList<Interval> intervals)
{
for (int i = 1; i < intervals.size(); i++)
int n = intervals.size();
for (int i = n - 2; i >= 0; i--)
{
Interval curr = intervals.get(i);
Interval prev = intervals.get(i - 1);
Interval next = intervals.get(i + 1);
int gap = prev.end.daysUntil(curr.begin) - 1;
if (gap <= 0 || curr.end.minus(gap).isOlderThan(curr.center)) continue;
intervals.set(i, new Interval(curr.begin.minus(gap), curr.center,
curr.end.minus(gap)));
int gapNextToCurrent = next.begin.daysUntil(curr.end);
int gapCenterToEnd = curr.center.daysUntil(curr.end);
if (gapNextToCurrent >= 0)
{
int shift = Math.min(gapCenterToEnd, gapNextToCurrent + 1);
intervals.set(i, new Interval(curr.begin.minus(shift),
curr.center,
curr.end.minus(shift)));
}
}
}

@ -319,16 +319,31 @@ public class CheckmarkListTest extends BaseUnitTest
public void test_snapIntervalsTogether_1() throws Exception
{
ArrayList<CheckmarkList.Interval> original = new ArrayList<>();
original.add(new CheckmarkList.Interval(day(40), day(40), day(34)));
original.add(new CheckmarkList.Interval(day(25), day(25), day(19)));
original.add(new CheckmarkList.Interval(day(16), day(16), day(10)));
original.add(new CheckmarkList.Interval(day(27), day(27), day(21)));
original.add(new CheckmarkList.Interval(day(20), day(20), day(14)));
original.add(new CheckmarkList.Interval(day(12), day(12), day(6)));
original.add(new CheckmarkList.Interval(day(8), day(8), day(2)));
ArrayList<CheckmarkList.Interval> expected = new ArrayList<>();
expected.add(new CheckmarkList.Interval(day(40), day(40), day(34)));
expected.add(new CheckmarkList.Interval(day(25), day(25), day(19)));
expected.add(new CheckmarkList.Interval(day(18), day(16), day(12)));
expected.add(new CheckmarkList.Interval(day(11), day(8), day(5)));
expected.add(new CheckmarkList.Interval(day(29), day(27), day(23)));
expected.add(new CheckmarkList.Interval(day(22), day(20), day(16)));
expected.add(new CheckmarkList.Interval(day(15), day(12), day(9)));
expected.add(new CheckmarkList.Interval(day(8), day(8), day(2)));
CheckmarkList.snapIntervalsTogether(original);
assertThat(original, equalTo(expected));
}
@Test
public void test_snapIntervalsTogether_2() throws Exception
{
ArrayList<CheckmarkList.Interval> original = new ArrayList<>();
original.add(new CheckmarkList.Interval(day(11), day(8), day(5)));
original.add(new CheckmarkList.Interval(day(6), day(4), day(0)));
ArrayList<CheckmarkList.Interval> expected = new ArrayList<>();
expected.add(new CheckmarkList.Interval(day(13), day(8), day(7)));
expected.add(new CheckmarkList.Interval(day(6), day(4), day(0)));
CheckmarkList.snapIntervalsTogether(original);
assertThat(original, equalTo(expected));

@ -153,9 +153,9 @@ public class ScoreListTest extends BaseUnitTest
habit.getScores().groupBy(DateUtils.TruncateField.MONTH, Calendar.SATURDAY);
assertThat(list.size(), equalTo(5));
assertThat(list.get(0).getValue(), closeTo(0.653659, E));
assertThat(list.get(1).getValue(), closeTo(0.622715, E));
assertThat(list.get(2).getValue(), closeTo(0.520997, E));
assertThat(list.get(0).getValue(), closeTo(0.687724, E));
assertThat(list.get(1).getValue(), closeTo(0.636747, E));
assertThat(list.get(2).getValue(), closeTo(0.533860, E));
}
@Test

Loading…
Cancel
Save