core -> kt, move tests to core

This commit is contained in:
Milos Kozak 2021-03-07 00:49:18 +01:00
parent 9b78839f5d
commit 72176edfb9
39 changed files with 636 additions and 580 deletions

View file

@ -250,8 +250,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (!t.isValid) continue; if (!t.isValid) continue;
if (t.date > time) continue; if (t.date > time) continue;
Iob tIOB = t.iobCalc(time, dia); Iob tIOB = t.iobCalc(time, dia);
total.iob += tIOB.iobContrib; total.iob += tIOB.getIobContrib();
total.activity += tIOB.activityContrib; total.activity += tIOB.getActivityContrib();
if (t.insulin > 0 && t.date > total.lastBolusTime) if (t.insulin > 0 && t.date > total.lastBolusTime)
total.lastBolusTime = t.date; total.lastBolusTime = t.date;
if (!t.isSMB) { if (!t.isSMB) {
@ -260,7 +260,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
long timeSinceTreatment = time - t.date; long timeSinceTreatment = time - t.date;
long snoozeTime = t.date + (long) (timeSinceTreatment * sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0)); long snoozeTime = t.date + (long) (timeSinceTreatment * sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0));
Iob bIOB = t.iobCalc(snoozeTime, dia); Iob bIOB = t.iobCalc(snoozeTime, dia);
total.bolussnooze += bIOB.iobContrib; total.bolussnooze += bIOB.getIobContrib();
} }
} }
} }
@ -476,8 +476,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
treatment.date = i; treatment.date = i;
treatment.insulin = running * 5.0 / 60.0; // 5 min chunk treatment.insulin = running * 5.0 / 60.0; // 5 min chunk
Iob iob = treatment.iobCalc(time, profile.getDia()); Iob iob = treatment.iobCalc(time, profile.getDia());
total.basaliob += iob.iobContrib; total.basaliob += iob.getIobContrib();
total.activity += iob.activityContrib; total.activity += iob.getActivityContrib();
} }
return total; return total;
} }

View file

@ -1,47 +0,0 @@
package info.nightscout.androidaps.data;
/**
* Created by mike on 05.06.2016.
*/
public class Iob {
public double iobContrib = 0d;
public double activityContrib = 0d;
public Iob iobContrib(double iobContrib) {
this.iobContrib = iobContrib;
return this;
}
public Iob activityContrib(double activityContrib) {
this.activityContrib = activityContrib;
return this;
}
public Iob plus(Iob iob) {
iobContrib += iob.iobContrib;
activityContrib += iob.activityContrib;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Iob iob = (Iob) o;
if (Double.compare(iob.iobContrib, iobContrib) != 0) return false;
return Double.compare(iob.activityContrib, activityContrib) == 0;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(iobContrib);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(activityContrib);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
}

View file

@ -0,0 +1,40 @@
package info.nightscout.androidaps.data
class Iob {
var iobContrib = 0.0
var activityContrib = 0.0
fun iobContrib(iobContrib: Double): Iob {
this.iobContrib = iobContrib
return this
}
fun activityContrib(activityContrib: Double): Iob {
this.activityContrib = activityContrib
return this
}
operator fun plus(iob: Iob): Iob {
iobContrib += iob.iobContrib
activityContrib += iob.activityContrib
return this
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val iob = other as Iob
return if (iob.iobContrib.compareTo(iobContrib) != 0) false
else iob.activityContrib.compareTo(activityContrib) == 0
}
override fun hashCode(): Int {
var result: Int
var temp: Long = java.lang.Double.doubleToLongBits(iobContrib)
result = (temp xor (temp ushr 32)).toInt()
temp = java.lang.Double.doubleToLongBits(activityContrib)
result = 31 * result + (temp xor (temp ushr 32)).toInt()
return result
}
}

View file

@ -1,190 +0,0 @@
package info.nightscout.androidaps.data;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Date;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.Round;
public class IobTotal implements DataPointWithLabelInterface {
public double iob;
public double activity;
public double bolussnooze;
public double basaliob;
public double netbasalinsulin;
public double hightempinsulin;
// oref1
public long lastBolusTime;
public IobTotal iobWithZeroTemp;
public double netInsulin = 0d; // for calculations from temp basals only
public double netRatio = 0d; // net ratio at start of temp basal
public double extendedBolusInsulin = 0d; // total insulin for extended bolus
long time;
public IobTotal copy() {
IobTotal i = new IobTotal(time);
i.iob = iob;
i.activity = activity;
i.bolussnooze = bolussnooze;
i.basaliob = basaliob;
i.netbasalinsulin = netbasalinsulin;
i.hightempinsulin = hightempinsulin;
i.lastBolusTime = lastBolusTime;
if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp.copy();
i.netInsulin = netInsulin;
i.netRatio = netRatio;
i.extendedBolusInsulin = extendedBolusInsulin;
return i;
}
public IobTotal(long time) {
this.iob = 0d;
this.activity = 0d;
this.bolussnooze = 0d;
this.basaliob = 0d;
this.netbasalinsulin = 0d;
this.hightempinsulin = 0d;
this.lastBolusTime = 0;
this.time = time;
}
public IobTotal plus(IobTotal other) {
iob += other.iob;
activity += other.activity;
bolussnooze += other.bolussnooze;
basaliob += other.basaliob;
netbasalinsulin += other.netbasalinsulin;
hightempinsulin += other.hightempinsulin;
netInsulin += other.netInsulin;
extendedBolusInsulin += other.extendedBolusInsulin;
return this;
}
public static IobTotal combine(IobTotal bolusIOB, IobTotal basalIob) {
IobTotal result = new IobTotal(bolusIOB.time);
result.iob = bolusIOB.iob + basalIob.basaliob;
result.activity = bolusIOB.activity + basalIob.activity;
result.bolussnooze = bolusIOB.bolussnooze;
result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin;
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin;
result.lastBolusTime = bolusIOB.lastBolusTime;
result.iobWithZeroTemp = basalIob.iobWithZeroTemp;
return result;
}
public IobTotal round() {
this.iob = Round.roundTo(this.iob, 0.001);
this.activity = Round.roundTo(this.activity, 0.0001);
this.bolussnooze = Round.roundTo(this.bolussnooze, 0.0001);
this.basaliob = Round.roundTo(this.basaliob, 0.001);
this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001);
this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001);
this.netInsulin = Round.roundTo(this.netInsulin, 0.001);
this.extendedBolusInsulin = Round.roundTo(this.extendedBolusInsulin, 0.001);
return this;
}
public JSONObject json() {
JSONObject json = new JSONObject();
try {
json.put("iob", iob);
json.put("basaliob", basaliob);
json.put("activity", activity);
json.put("time", DateUtil.toISOString(new Date()));
} catch (JSONException ignored) {
}
return json;
}
public JSONObject determineBasalJson() {
JSONObject json = new JSONObject();
try {
json.put("iob", iob);
json.put("basaliob", basaliob);
json.put("bolussnooze", bolussnooze);
json.put("activity", activity);
json.put("lastBolusTime", lastBolusTime);
json.put("time", DateUtil.toISOString(new Date(time)));
/*
This is requested by SMB determine_basal but by based on Scott's info
it's MDT specific safety check only
It's causing rounding issues in determine_basal
JSONObject lastTemp = new JSONObject();
lastTemp.put("date", lastTempDate);
lastTemp.put("rate", lastTempRate);
lastTemp.put("duration", lastTempDuration);
json.put("lastTemp", lastTemp);
*/
if (iobWithZeroTemp != null) {
JSONObject iwzt = iobWithZeroTemp.determineBasalJson();
json.put("iobWithZeroTemp", iwzt);
}
} catch (JSONException ignored) {
}
return json;
}
// DataPoint interface
private int color;
@Override
public double getX() {
return time;
}
@Override
public double getY() {
return iob;
}
@Override
public void setY(double y) {
}
@Override
public String getLabel() {
return null;
}
@Override
public long getDuration() {
return 0;
}
@Override
public PointsWithLabelGraphSeries.Shape getShape() {
return PointsWithLabelGraphSeries.Shape.IOBPREDICTION;
}
@Override
public float getSize() {
return 0.5f;
}
@Override
public int getColor() {
return color;
}
public IobTotal setColor(int color) {
this.color = color;
return this;
}
}

View file

@ -0,0 +1,163 @@
package info.nightscout.androidaps.data
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.Round
import org.json.JSONException
import org.json.JSONObject
import java.util.*
@Suppress("SpellCheckingInspection")
class IobTotal(var time: Long) : DataPointWithLabelInterface {
@JvmField var iob = 0.0
@JvmField var activity = 0.0
@JvmField var bolussnooze = 0.0
@JvmField var basaliob = 0.0
@JvmField var netbasalinsulin = 0.0
@JvmField var hightempinsulin = 0.0
// oref1
@JvmField var lastBolusTime: Long = 0
var iobWithZeroTemp: IobTotal? = null
@JvmField var netInsulin = 0.0 // for calculations from temp basals only
@JvmField var netRatio = 0.0 // net ratio at start of temp basal
@JvmField var extendedBolusInsulin = 0.0 // total insulin for extended bolus
fun copy(): IobTotal {
val i = IobTotal(time)
i.iob = iob
i.activity = activity
i.bolussnooze = bolussnooze
i.basaliob = basaliob
i.netbasalinsulin = netbasalinsulin
i.hightempinsulin = hightempinsulin
i.lastBolusTime = lastBolusTime
if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp!!.copy()
i.netInsulin = netInsulin
i.netRatio = netRatio
i.extendedBolusInsulin = extendedBolusInsulin
return i
}
operator fun plus(other: IobTotal): IobTotal {
iob += other.iob
activity += other.activity
bolussnooze += other.bolussnooze
basaliob += other.basaliob
netbasalinsulin += other.netbasalinsulin
hightempinsulin += other.hightempinsulin
netInsulin += other.netInsulin
extendedBolusInsulin += other.extendedBolusInsulin
return this
}
fun round(): IobTotal {
iob = Round.roundTo(iob, 0.001)
activity = Round.roundTo(activity, 0.0001)
bolussnooze = Round.roundTo(bolussnooze, 0.0001)
basaliob = Round.roundTo(basaliob, 0.001)
netbasalinsulin = Round.roundTo(netbasalinsulin, 0.001)
hightempinsulin = Round.roundTo(hightempinsulin, 0.001)
netInsulin = Round.roundTo(netInsulin, 0.001)
extendedBolusInsulin = Round.roundTo(extendedBolusInsulin, 0.001)
return this
}
fun json(): JSONObject {
val json = JSONObject()
try {
json.put("iob", iob)
json.put("basaliob", basaliob)
json.put("activity", activity)
json.put("time", DateUtil.toISOString(Date()))
} catch (ignored: JSONException) {
}
return json
}
fun determineBasalJson(): JSONObject {
val json = JSONObject()
try {
json.put("iob", iob)
json.put("basaliob", basaliob)
json.put("bolussnooze", bolussnooze)
json.put("activity", activity)
json.put("lastBolusTime", lastBolusTime)
json.put("time", DateUtil.toISOString(Date(time)))
/*
This is requested by SMB determine_basal but by based on Scott's info
it's MDT specific safety check only
It's causing rounding issues in determine_basal
JSONObject lastTemp = new JSONObject();
lastTemp.put("date", lastTempDate);
lastTemp.put("rate", lastTempRate);
lastTemp.put("duration", lastTempDuration);
json.put("lastTemp", lastTemp);
*/
if (iobWithZeroTemp != null) {
val iwzt = iobWithZeroTemp!!.determineBasalJson()
json.put("iobWithZeroTemp", iwzt)
}
} catch (ignored: JSONException) {
}
return json
}
// DataPoint interface
private var color = 0
override fun getX(): Double {
return time.toDouble()
}
override fun getY(): Double {
return iob
}
override fun setY(y: Double) {}
override fun getLabel(): String {
return ""
}
override fun getDuration(): Long {
return 0
}
override fun getShape(): PointsWithLabelGraphSeries.Shape {
return PointsWithLabelGraphSeries.Shape.IOBPREDICTION
}
override fun getSize(): Float {
return 0.5f
}
override fun getColor(): Int {
return color
}
fun setColor(color: Int): IobTotal {
this.color = color
return this
}
companion object {
fun combine(bolusIOB: IobTotal, basalIob: IobTotal): IobTotal {
val result = IobTotal(bolusIOB.time)
result.iob = bolusIOB.iob + basalIob.basaliob
result.activity = bolusIOB.activity + basalIob.activity
result.bolussnooze = bolusIOB.bolussnooze
result.basaliob = bolusIOB.basaliob + basalIob.basaliob
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin
result.lastBolusTime = bolusIOB.lastBolusTime
result.iobWithZeroTemp = basalIob.iobWithZeroTemp
return result
}
}
}

View file

@ -1,15 +0,0 @@
package info.nightscout.androidaps.data;
/**
* Created by mike on 04.01.2017.
*/
public class MealData {
public double boluses = 0d;
public double carbs = 0d;
public double mealCOB = 0.0d;
public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999;
public long lastBolusTime;
public long lastCarbTime = 0L;
public double usedMinCarbsImpact = 0d;
}

View file

@ -0,0 +1,13 @@
package info.nightscout.androidaps.data
class MealData {
var boluses = 0.0
var carbs = 0.0
var mealCOB = 0.0
var slopeFromMaxDeviation = 0.0
var slopeFromMinDeviation = 999.0
var lastBolusTime: Long = 0
var lastCarbTime = 0L
var usedMinCarbsImpact = 0.0
}

View file

@ -1,39 +0,0 @@
package info.nightscout.androidaps.data;
import androidx.annotation.Nullable;
import info.nightscout.androidaps.interfaces.Interval;
/**
* Created by adrian on 15/07/17.
*/
public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
public NonOverlappingIntervals() {
super();
}
public NonOverlappingIntervals (Intervals<T> other) {
rawData = other.rawData.clone();
}
public synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index);
long startOfNewer = rawData.valueAt(index + 1).start();
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer);
}
}
}
@Nullable
public synchronized T getValueByInterval(long time) {
int index = binarySearch(time);
if (index >= 0) return rawData.valueAt(index);
return null;
}
}

View file

@ -0,0 +1,26 @@
package info.nightscout.androidaps.data
import info.nightscout.androidaps.interfaces.Interval
class NonOverlappingIntervals<T : Interval> : Intervals<T> {
constructor() : super()
constructor(other: Intervals<T>) {
rawData = other.rawData.clone()
}
@Synchronized public override fun merge() {
for (index in 0 until rawData.size() - 1) {
val i: T = rawData.valueAt(index)
val startOfNewer = rawData.valueAt(index + 1).start()
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer)
}
}
}
@Synchronized override fun getValueByInterval(time: Long): T? {
val index = binarySearch(time)
return if (index >= 0) rawData.valueAt(index) else null
}
}

View file

@ -1,51 +0,0 @@
package info.nightscout.androidaps.data;
import androidx.annotation.Nullable;
import info.nightscout.androidaps.interfaces.Interval;
/**
* Created by adrian on 15/07/17.
*/
public class OverlappingIntervals<T extends Interval> extends Intervals<T> {
public OverlappingIntervals() {
super();
}
public OverlappingIntervals(Intervals<T> other) {
rawData = other.rawData.clone();
}
protected synchronized void merge() {
boolean needToCut = false;
long cutTime = 0;
for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest
Interval cur = rawData.valueAt(index);
if (cur.isEndingEvent()) {
needToCut = true;
cutTime = cur.start();
} else {
//event that is no EndingEvent might need to be stopped by an ending event
if (needToCut && cur.end() > cutTime) {
cur.cutEndTo(cutTime);
}
}
}
}
@Nullable
public synchronized T getValueByInterval(long time) {
for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest
T cur = rawData.valueAt(index);
if (cur.match(time)) {
return cur;
}
}
return null;
}
}

View file

@ -0,0 +1,38 @@
package info.nightscout.androidaps.data
import info.nightscout.androidaps.interfaces.Interval
class OverlappingIntervals<T : Interval> : Intervals<T> {
constructor() : super()
constructor(other: Intervals<T>) {
rawData = other.rawData.clone()
}
@Synchronized override fun merge() {
var needToCut = false
var cutTime: Long = 0
for (index in rawData.size() - 1 downTo 0) { //begin with newest
val cur: Interval = rawData.valueAt(index)
if (cur.isEndingEvent) {
needToCut = true
cutTime = cur.start()
} else {
//event that is no EndingEvent might need to be stopped by an ending event
if (needToCut && cur.end() > cutTime) {
cur.cutEndTo(cutTime)
}
}
}
}
@Synchronized override fun getValueByInterval(time: Long): T? {
for (index in rawData.size() - 1 downTo 0) { //begin with newest
val cur = rawData.valueAt(index)
if (cur!!.match(time)) {
return cur
}
}
return null
}
}

View file

@ -1,132 +0,0 @@
package info.nightscout.androidaps.data;
import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.interfaces.Interval;
/**
* Created by mike on 09.05.2017.
*/
// Zero duration means profile is valid until is chaged
// When no interval match the lastest record without duration is used
public class ProfileIntervals<T extends Interval> {
private LongSparseArray<T> rawData; // oldest at index 0
public ProfileIntervals() {
rawData = new LongSparseArray<>();
}
public ProfileIntervals(ProfileIntervals<T> other) {
rawData = other.rawData.clone();
}
public synchronized ProfileIntervals<T> reset() {
rawData = new LongSparseArray<>();
return this;
}
public synchronized void add(T newInterval) {
if (newInterval.isValid()) {
rawData.put(newInterval.start(), newInterval);
merge();
}
}
public synchronized void add(List<T> list) {
for (T interval : list) {
if (interval.isValid())
rawData.put(interval.start(), interval);
}
merge();
}
private synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index);
long startOfNewer = rawData.valueAt(index + 1).start();
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer);
}
}
}
@Nullable
public synchronized Interval getValueToTime(long time) {
int index = binarySearch(time);
if (index >= 0) return rawData.valueAt(index);
// if we request data older than first record, use oldest with zero duration instead
for (index = 0; index < rawData.size(); index++) {
if (rawData.valueAt(index).durationInMsec() == 0) {
//log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
return rawData.valueAt(index);
}
}
return null;
}
public synchronized List<T> getList() {
List<T> list = new ArrayList<>();
for (int i = 0; i < rawData.size(); i++)
list.add(rawData.valueAt(i));
return list;
}
public synchronized List<T> getReversedList() {
List<T> list = new ArrayList<>();
for (int i = rawData.size() - 1; i >= 0; i--)
list.add(rawData.valueAt(i));
return list;
}
private synchronized int binarySearch(long value) {
if (rawData.size() == 0)
return -1;
int lo = 0;
int hi = rawData.size() - 1;
while (lo <= hi) {
final int mid = (lo + hi) >>> 1;
final Interval midVal = rawData.valueAt(mid);
if (midVal.match(value)) {
return mid; // value found
} else if (midVal.before(value)) {
lo = mid + 1;
} else if (midVal.after(value)) {
hi = mid - 1;
}
}
// not found, try nearest older with duration 0
lo = lo - 1;
while (lo >= 0 && lo < rawData.size()) {
if (rawData.valueAt(lo).isEndingEvent())
return lo;
lo--;
}
return -1; // value not present
}
public synchronized int size() {
return rawData.size();
}
public synchronized T get(int index) {
return rawData.valueAt(index);
}
public synchronized T getReversed(int index) {
return rawData.valueAt(size() - 1 - index);
}
@Override
public String toString() {
return rawData.toString();
}
}

View file

@ -0,0 +1,115 @@
package info.nightscout.androidaps.data
import androidx.collection.LongSparseArray
import info.nightscout.androidaps.interfaces.Interval
import java.util.*
// Zero duration means profile is valid until is changed
// When no interval match the latest record without duration is used
class ProfileIntervals<T : Interval> {
private var rawData: LongSparseArray<T> // oldest at index 0
constructor() {
rawData = LongSparseArray()
}
constructor(other: ProfileIntervals<T>) {
rawData = other.rawData.clone()
}
@Synchronized fun reset(): ProfileIntervals<T> {
rawData = LongSparseArray()
return this
}
@Synchronized fun add(newInterval: T) {
if (newInterval.isValid) {
rawData.put(newInterval.start(), newInterval)
merge()
}
}
@Synchronized fun add(list: List<T>) {
for (interval in list) {
if (interval.isValid) rawData.put(interval.start(), interval)
}
merge()
}
@Synchronized private fun merge() {
for (index in 0 until rawData.size() - 1) {
val i: T = rawData.valueAt(index)
val startOfNewer = rawData.valueAt(index + 1)!!.start()
if (i.originalEnd() > startOfNewer) {
i.cutEndTo(startOfNewer)
}
}
}
@Synchronized fun getValueToTime(time: Long): Interval? {
var index = binarySearch(time)
if (index >= 0) return rawData.valueAt(index)
// if we request data older than first record, use oldest with zero duration instead
index = 0
while (index < rawData.size()) {
if (rawData.valueAt(index)!!.durationInMsec() == 0L) {
//log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
return rawData.valueAt(index)
}
index++
}
return null
}
@get:Synchronized val list: List<T>
get() {
val list: MutableList<T> = ArrayList()
for (i in 0 until rawData.size()) list.add(rawData.valueAt(i))
return list
}
@get:Synchronized val reversedList: List<T>
get() {
val list: MutableList<T> = ArrayList()
for (i in rawData.size() - 1 downTo 0) list.add(rawData.valueAt(i))
return list
}
@Synchronized private fun binarySearch(value: Long): Int {
if (rawData.size() == 0) return -1
var lo = 0
var hi = rawData.size() - 1
while (lo <= hi) {
val mid = lo + hi ushr 1
val midVal: Interval = rawData.valueAt(mid)
when {
midVal.match(value) -> return mid // value found
midVal.before(value) -> lo = mid + 1
midVal.after(value) -> hi = mid - 1
}
}
// not found, try nearest older with duration 0
lo -= 1
while (lo >= 0 && lo < rawData.size()) {
if (rawData.valueAt(lo)!!.isEndingEvent) return lo
lo--
}
return -1 // value not present
}
@Synchronized fun size(): Int {
return rawData.size()
}
@Synchronized operator fun get(index: Int): T? {
return rawData.valueAt(index)
}
@Synchronized fun getReversed(index: Int): T {
return rawData.valueAt(size() - 1 - index)
}
override fun toString(): String {
return rawData.toString()
}
}

View file

@ -254,8 +254,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.iob += aIOB.iobContrib; result.iob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.extendedBolusInsulin += tempBolusPart.insulin; result.extendedBolusInsulin += tempBolusPart.insulin;
} }
} }
@ -305,8 +305,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.iob += aIOB.iobContrib; result.iob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.extendedBolusInsulin += tempBolusPart.insulin; result.extendedBolusInsulin += tempBolusPart.insulin;
} }
} }

View file

@ -285,8 +285,8 @@ public class TemporaryBasal implements Interval, DbObjectBase {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.basaliob += aIOB.iobContrib; result.basaliob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.netbasalinsulin += tempBolusPart.insulin; result.netbasalinsulin += tempBolusPart.insulin;
if (tempBolusPart.insulin > 0) { if (tempBolusPart.insulin > 0) {
result.hightempinsulin += tempBolusPart.insulin; result.hightempinsulin += tempBolusPart.insulin;
@ -352,8 +352,8 @@ public class TemporaryBasal implements Interval, DbObjectBase {
tempBolusPart.date = calcdate; tempBolusPart.date = calcdate;
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
result.basaliob += aIOB.iobContrib; result.basaliob += aIOB.getIobContrib();
result.activity += aIOB.activityContrib; result.activity += aIOB.getActivityContrib();
result.netbasalinsulin += tempBolusPart.insulin; result.netbasalinsulin += tempBolusPart.insulin;
if (tempBolusPart.insulin > 0) { if (tempBolusPart.insulin > 0) {
result.hightempinsulin += tempBolusPart.insulin; result.hightempinsulin += tempBolusPart.insulin;

View file

@ -0,0 +1,82 @@
package info.nightscout.androidaps
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.db.Treatment
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.ConfigInterface
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.interfaces.TreatmentsInterface
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONObject
import org.junit.Before
import org.mockito.Mock
import org.powermock.core.classloader.annotations.PrepareForTest
@Suppress("SpellCheckingInspection")
@PrepareForTest(FabricPrivacy::class)
open class TestBaseWithProfile : TestBase() {
@Mock lateinit var activePluginProvider: ActivePluginProvider
@Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var treatmentsInterface: TreatmentsInterface
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var defaultValueHelper: DefaultValueHelper
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var configInterface: ConfigInterface
val rxBus = RxBusWrapper(aapsSchedulers)
val profileInjector = HasAndroidInjector {
AndroidInjector {
if (it is Profile) {
it.aapsLogger = aapsLogger
it.activePlugin = activePluginProvider
it.resourceHelper = resourceHelper
it.rxBus = rxBus
it.fabricPrivacy = fabricPrivacy
it.configInterface = configInterface
}
if (it is ProfileSwitch) {
it.treatmentsPlugin = treatmentsInterface
it.aapsLogger = aapsLogger
it.rxBus = rxBus
it.resourceHelper = resourceHelper
it.dateUtil = dateUtil
}
if (it is Treatment) {
it.activePlugin = activePluginProvider
it.profileFunction = profileFunction
it.defaultValueHelper = defaultValueHelper
it.resourceHelper = resourceHelper
}
}
}
private lateinit var validProfileJSON: String
lateinit var validProfile: Profile
@Suppress("PropertyName") val TESTPROFILENAME = "someProfile"
@Before
fun prepareMock() {
validProfileJSON = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
validProfile = Profile(profileInjector, JSONObject(validProfileJSON), Constants.MGDL)
}
fun getValidProfileStore(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStore(profileInjector, json)
}
}

View file

@ -0,0 +1,67 @@
package info.nightscout.androidaps
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.PumpInterface
import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.TimeChangeType
import org.json.JSONObject
@Suppress("MemberVisibilityCanBePrivate")
class TestPumpPlugin(val injector: HasAndroidInjector) : PumpInterface {
var connected = false
var isProfileSet = true
override fun isConnected() = connected
override fun isConnecting() = false
override fun isHandshakeInProgress() = false
val lastData = 0L
val baseBasal = 0.0
override val pumpDescription = PumpDescription()
override fun isInitialized(): Boolean = true
override fun isSuspended(): Boolean = false
override fun isBusy(): Boolean = false
override fun connect(reason: String) {
connected = true
}
override fun disconnect(reason: String) {
connected = false
}
override fun stopConnecting() {
connected = false
}
override fun waitForDisconnectionInSeconds(): Int = 0
override fun getPumpStatus(reason: String) {}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector)
override fun isThisProfileSet(profile: Profile): Boolean = isProfileSet
override fun lastDataTime(): Long = lastData
override val baseBasalRate: Double = baseBasal
override val reservoirLevel: Double = 0.0
override val batteryLevel: Int = 0
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun stopBolusDelivering() {}
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject()
override fun manufacturer(): ManufacturerType = ManufacturerType.AndroidAPS
override fun model(): PumpType = PumpType.GenericAAPS
override fun serialNumber(): String = "1"
override fun shortStatus(veryShort: Boolean): String = ""
override val isFakingTempsByExtendedBoluses: Boolean = false
override fun loadTDDs(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun canHandleDST(): Boolean = true
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {}
}

View file

@ -1,14 +1,12 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.data
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mock
import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@ -16,7 +14,7 @@ import org.powermock.modules.junit4.PowerMockRunner
* Created by mike on 19.03.2018. * Created by mike on 19.03.2018.
*/ */
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(MainApp::class, SP::class) @PrepareForTest(SP::class)
class ConstraintTest : TestBase() { class ConstraintTest : TestBase() {
@Test fun doTests() { @Test fun doTests() {

View file

@ -23,6 +23,7 @@ class IobTest {
Assert.assertTrue(a1 == a1) Assert.assertTrue(a1 == a1)
Assert.assertTrue(a1 == a2) Assert.assertTrue(a1 == a2)
Assert.assertFalse(a1 == b) Assert.assertFalse(a1 == b)
@Suppress("SENSELESS_COMPARISON")
Assert.assertFalse(a1 == null) Assert.assertFalse(a1 == null)
Assert.assertFalse(a1 == Any()) Assert.assertFalse(a1 == Any())
} }

View file

@ -6,11 +6,12 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@Suppress("SpellCheckingInspection")
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
class IobTotalTest { class IobTotalTest {
var now = DateUtil.now() var now = DateUtil.now()
@Test fun copytest() { @Test fun copyTest() {
val a = IobTotal(now) val a = IobTotal(now)
a.iob = 10.0 a.iob = 10.0
val b = a.copy() val b = a.copy()

View file

@ -1,41 +1,31 @@
package info.nightscout.androidaps.data package info.nightscout.androidaps.data
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.db.ProfileSwitch import info.nightscout.androidaps.db.ProfileSwitch
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when` import org.mockito.Mockito.`when`
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
import java.util.* import java.util.*
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(VirtualPumpPlugin::class)
class ProfileIntervalsTest : TestBaseWithProfile() { class ProfileIntervalsTest : TestBaseWithProfile() {
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin lateinit var testPumpPlugin: TestPumpPlugin
private val startDate = DateUtil.now() private val startDate = DateUtil.now()
var list = ProfileIntervals<ProfileSwitch>() var list = ProfileIntervals<ProfileSwitch>()
@Before @Before
fun mock() { fun mock() {
`when`(activePluginProvider.activePump).thenReturn(virtualPumpPlugin) testPumpPlugin = TestPumpPlugin(profileInjector)
`when`(virtualPumpPlugin.pumpDescription).thenReturn(PumpDescription()) `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
} }
@Test @Test
fun doTests() { fun doTests() {
// create one 10h interval and test value in and out // create one 10h interval and test value in and out
@ -83,7 +73,7 @@ class ProfileIntervalsTest : TestBaseWithProfile() {
someList.add(ProfileSwitch(profileInjector).date(startDate + T.hours(1).msecs()).duration(T.hours(1).mins().toInt()).profileName("6").profile(validProfile)) someList.add(ProfileSwitch(profileInjector).date(startDate + T.hours(1).msecs()).duration(T.hours(1).mins().toInt()).profileName("6").profile(validProfile))
list.reset() list.reset()
list.add(someList) list.add(someList)
Assert.assertEquals(startDate, list[0].date) Assert.assertEquals(startDate, list[0]?.date)
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date) Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date)
Assert.assertEquals(startDate + T.hours(1).msecs(), list.reversedList[0].date) Assert.assertEquals(startDate + T.hours(1).msecs(), list.reversedList[0].date)
} }

View file

@ -1,17 +1,16 @@
package info.nightscout.androidaps.data package info.nightscout.androidaps.data
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import org.json.JSONObject import org.json.JSONObject
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when` import org.mockito.Mockito.`when`
import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@ -21,27 +20,26 @@ import java.util.*
/** /**
* Created by mike on 18.03.2018. * Created by mike on 18.03.2018.
*/ */
@Suppress("SpellCheckingInspection")
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(VirtualPumpPlugin::class, FabricPrivacy::class) @PrepareForTest(FabricPrivacy::class)
class ProfileTest : TestBaseWithProfile() { class ProfileTest : TestBaseWithProfile() {
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin private lateinit var testPumpPlugin: TestPumpPlugin
var okProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" private var okProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
var belowLimitValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.001\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" private var belowLimitValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.001\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
var notAllignedBasalValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:30\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" private var notAlignedBasalValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:30\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
var notStartingAtZeroValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:30\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" private var notStartingAtZeroValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:30\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
var noUnitsValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\"}" private var noUnitsValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\"}"
var wrongProfile = "{\"dia\":\"3\",\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" private var wrongProfile = "{\"dia\":\"3\",\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
//String profileStore = "{\"defaultProfile\":\"Default\",\"store\":{\"Default\":" + validProfile + "}}"; //String profileStore = "{\"defaultProfile\":\"Default\",\"store\":{\"Default\":" + validProfile + "}}";
val pumpDescription = PumpDescription()
@Before @Before
fun prepare() { fun prepare() {
`when`(activePluginProvider.activePump).thenReturn(virtualPumpPlugin) testPumpPlugin = TestPumpPlugin(profileInjector)
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription) `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
`when`(resourceHelper.gs(R.string.profile_per_unit)).thenReturn("/U") `when`(resourceHelper.gs(R.string.profile_per_unit)).thenReturn("/U")
`when`(resourceHelper.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U") `when`(resourceHelper.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U")
`when`(resourceHelper.gs(R.string.profile_ins_units_per_hour)).thenReturn("U/h") `when`(resourceHelper.gs(R.string.profile_ins_units_per_hour)).thenReturn("U/h")
@ -51,7 +49,7 @@ class ProfileTest : TestBaseWithProfile() {
fun doTests() { fun doTests() {
// Test valid profile // Test valid profile
var p: Profile = Profile(profileInjector, JSONObject(okProfile), 100, 0) var p = Profile(profileInjector, JSONObject(okProfile), 100, 0)
Assert.assertEquals(true, p.isValid("Test")) Assert.assertEquals(true, p.isValid("Test"))
Assert.assertEquals(true, p.log().contains("NS units: mmol")) Assert.assertEquals(true, p.log().contains("NS units: mmol"))
JSONAssert.assertEquals(okProfile, p.data, false) JSONAssert.assertEquals(okProfile, p.data, false)
@ -141,9 +139,9 @@ class ProfileTest : TestBaseWithProfile() {
""".trimIndent(), p.isfList) """.trimIndent(), p.isfList)
// Test hour alignment // Test hour alignment
pumpDescription.is30minBasalRatesCapable = false testPumpPlugin.pumpDescription.is30minBasalRatesCapable = false
//((AAPSMocker.MockedBus) MainApp.bus()).notificationSent = false; //((AAPSMocker.MockedBus) MainApp.bus()).notificationSent = false;
p = Profile(profileInjector, JSONObject(notAllignedBasalValidProfile), 100, 0) p = Profile(profileInjector, JSONObject(notAlignedBasalValidProfile), 100, 0)
p.isValid("Test") p.isValid("Test")
//Assert.assertEquals(true, ((AAPSMocker.MockedBus) MainApp.bus()).notificationSent); //Assert.assertEquals(true, ((AAPSMocker.MockedBus) MainApp.bus()).notificationSent);
} }

View file

@ -3,9 +3,8 @@ package info.nightscout.androidaps.data
import android.text.Html import android.text.Html
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.core.R
import org.json.JSONObject import org.json.JSONObject
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
@ -17,7 +16,7 @@ import org.powermock.modules.junit4.PowerMockRunner
import org.skyscreamer.jsonassert.JSONAssert import org.skyscreamer.jsonassert.JSONAssert
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(MainApp::class, Html::class) @PrepareForTest(Html::class)
class PumpEnactResultTest : TestBaseWithProfile() { class PumpEnactResultTest : TestBaseWithProfile() {
val injector = HasAndroidInjector { val injector = HasAndroidInjector {

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment import androidx.fragment.app.Fragment
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -15,8 +15,8 @@ class PluginDescriptionTest {
} }
@Test fun fragmentClassTest() { @Test fun fragmentClassTest() {
val pluginDescription = PluginDescription().fragmentClass(NSProfileFragment::class.java.name) val pluginDescription = PluginDescription().fragmentClass(Fragment::class.java.name)
Assert.assertEquals(NSProfileFragment::class.java.name, pluginDescription.getFragmentClass()) Assert.assertEquals(Fragment::class.java.name, pluginDescription.getFragmentClass())
} }
@Test fun alwaysEnabledTest() { @Test fun alwaysEnabledTest() {
@ -24,7 +24,7 @@ class PluginDescriptionTest {
Assert.assertEquals(true, pluginDescription.alwaysEnabled) Assert.assertEquals(true, pluginDescription.alwaysEnabled)
} }
@Test fun alwayVisibleTest() { @Test fun alwaysVisibleTest() {
val pluginDescription = PluginDescription().alwaysVisible(true) val pluginDescription = PluginDescription().alwaysVisible(true)
Assert.assertEquals(true, pluginDescription.alwaysVisible) Assert.assertEquals(true, pluginDescription.alwaysVisible)
} }

View file

@ -9,7 +9,7 @@ import org.junit.Test
/** /**
* Created by andy on 5/13/18. * Created by andy on 5/13/18.
*/ */
class PumpDescritpionTest { class PumpDescriptionTest {
@Test fun setPumpDescription() { @Test fun setPumpDescription() {
val pumpDescription = PumpDescription() val pumpDescription = PumpDescription()

View file

@ -3,12 +3,11 @@ package info.nightscout.androidaps.plugins.aps.loop
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.db.TemporaryBasal import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.utils.JsonHelper.safeGetDouble import info.nightscout.androidaps.utils.JsonHelper.safeGetDouble
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert
@ -22,22 +21,21 @@ import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, VirtualPumpPlugin::class) @PrepareForTest(ConstraintChecker::class)
class APSResultTest : TestBaseWithProfile() { class APSResultTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var constraintChecker: ConstraintChecker
@Mock lateinit var sp: SP @Mock lateinit var sp: SP
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
private lateinit var testPumpPlugin: TestPumpPlugin
private val injector = HasAndroidInjector { AndroidInjector { } } private val injector = HasAndroidInjector { AndroidInjector { } }
private var closedLoopEnabled = Constraint(false) private var closedLoopEnabled = Constraint(false)
private val pumpDescription = PumpDescription()
@Test @Test
fun changeRequestedTest() { fun changeRequestedTest() {
val apsResult = APSResult(HasAndroidInjector { AndroidInjector { Unit } }) val apsResult = APSResult { AndroidInjector { } }
.also { .also {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger
it.constraintChecker = constraintChecker it.constraintChecker = constraintChecker
@ -51,7 +49,7 @@ class APSResultTest : TestBaseWithProfile() {
// BASAL RATE IN TEST PROFILE IS 1U/h // BASAL RATE IN TEST PROFILE IS 1U/h
// **** PERCENT pump **** // **** PERCENT pump ****
pumpDescription.setPumpDescription(PumpType.Cellnovo1) // % based testPumpPlugin.pumpDescription.setPumpDescription(PumpType.Cellnovo1) // % based
apsResult.usePercent(true) apsResult.usePercent(true)
// closed loop mode return original request // closed loop mode return original request
@ -109,7 +107,7 @@ class APSResultTest : TestBaseWithProfile() {
Assert.assertEquals(true, apsResult.isChangeRequested) Assert.assertEquals(true, apsResult.isChangeRequested)
// **** ABSOLUTE pump **** // **** ABSOLUTE pump ****
virtualPumpPlugin.pumpDescription.setPumpDescription(PumpType.Medtronic_515_715) // U/h based testPumpPlugin.pumpDescription.setPumpDescription(PumpType.Medtronic_515_715) // U/h based
apsResult.usePercent(false) apsResult.usePercent(false)
// open loop // open loop
@ -158,7 +156,7 @@ class APSResultTest : TestBaseWithProfile() {
} }
@Test fun cloneTest() { @Test fun cloneTest() {
val apsResult = APSResult(HasAndroidInjector { AndroidInjector { Unit } }) val apsResult = APSResult { AndroidInjector { } }
.also { .also {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger
it.constraintChecker = constraintChecker it.constraintChecker = constraintChecker
@ -175,7 +173,7 @@ class APSResultTest : TestBaseWithProfile() {
@Test fun jsonTest() { @Test fun jsonTest() {
closedLoopEnabled.set(aapsLogger, true) closedLoopEnabled.set(aapsLogger, true)
val apsResult = APSResult(HasAndroidInjector { AndroidInjector { Unit } }) val apsResult = APSResult { AndroidInjector { } }
.also { .also {
it.aapsLogger = aapsLogger it.aapsLogger = aapsLogger
it.constraintChecker = constraintChecker it.constraintChecker = constraintChecker
@ -193,10 +191,10 @@ class APSResultTest : TestBaseWithProfile() {
@Before @Before
fun prepare() { fun prepare() {
testPumpPlugin = TestPumpPlugin(profileInjector)
`when`(constraintChecker.isClosedLoopAllowed()).thenReturn(closedLoopEnabled) `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(closedLoopEnabled)
`when`(activePluginProvider.activePump).thenReturn(virtualPumpPlugin) `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
`when`(sp.getDouble(ArgumentMatchers.anyInt(), ArgumentMatchers.anyDouble())).thenReturn(30.0) `when`(sp.getDouble(ArgumentMatchers.anyInt(), ArgumentMatchers.anyDouble())).thenReturn(30.0)
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
`when`(profileFunction.getProfile()).thenReturn(validProfile) `when`(profileFunction.getProfile()).thenReturn(validProfile)
} }
} }

View file

@ -1,9 +1,6 @@
package info.nightscout.androidaps.plugins.general.maintenance package info.nightscout.androidaps.plugins.general.maintenance.formats
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.plugins.general.maintenance.formats.ClassicPrefsFormat
import info.nightscout.androidaps.plugins.general.maintenance.formats.Prefs
import info.nightscout.androidaps.testing.utils.SingleStringStorage
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert

View file

@ -1,8 +1,6 @@
package info.nightscout.androidaps.plugins.general.maintenance package info.nightscout.androidaps.plugins.general.maintenance.formats
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.plugins.general.maintenance.formats.*
import info.nightscout.androidaps.testing.utils.SingleStringStorage
import info.nightscout.androidaps.utils.CryptoUtil import info.nightscout.androidaps.utils.CryptoUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.testing.utils package info.nightscout.androidaps.plugins.general.maintenance.formats
import info.nightscout.androidaps.utils.storage.Storage import info.nightscout.androidaps.utils.storage.Storage
import java.io.File import java.io.File

View file

@ -1,9 +1,11 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator package info.nightscout.androidaps.plugins.iob.iobCalculator
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import org.junit.Assert import org.junit.Assert
@ -20,12 +22,13 @@ import java.util.*
/** /**
* Created by mike on 26.03.2018. * Created by mike on 26.03.2018.
*/ */
@Suppress("SpellCheckingInspection")
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(IobCobCalculatorPlugin::class, DateUtil::class) @PrepareForTest(DateUtil::class)
class GlucoseStatusTest : TestBase() { class GlucoseStatusTest : TestBase() {
@Mock lateinit var dateUtil: DateUtil @Mock lateinit var dateUtil: DateUtil
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin @Mock lateinit var iobCobCalculatorPlugin: IobCobCalculatorInterface
val injector = HasAndroidInjector { val injector = HasAndroidInjector {
AndroidInjector { AndroidInjector {
@ -80,7 +83,7 @@ class GlucoseStatusTest : TestBase() {
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date
} }
@Test fun insuffientDataShouldReturnNull() { @Test fun insufficientDataShouldReturnNull() {
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateInsufficientBgData()) PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateInsufficientBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatus(injector).glucoseStatusData val glucoseStatus: GlucoseStatus? = GlucoseStatus(injector).glucoseStatusData
Assert.assertEquals(null, glucoseStatus) Assert.assertEquals(null, glucoseStatus)

View file

@ -1,7 +1,8 @@
package info.nightscout.androidaps.plugins.pump.common.bolusInfo package info.nightscout.androidaps.pump.bolusInfo
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull import org.junit.Assert.assertNull
import org.junit.Before import org.junit.Before
@ -16,7 +17,7 @@ class DetailedBolusInfoStorageTest : TestBase() {
private val info2 = DetailedBolusInfo() private val info2 = DetailedBolusInfo()
private val info3 = DetailedBolusInfo() private val info3 = DetailedBolusInfo()
lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage private lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
init { init {
info1.date = 1000000 info1.date = 1000000

View file

@ -1,10 +1,12 @@
package info.nightscout.androidaps.plugins.pump.common.utils; package info.nightscout.androidaps.pump.common.utils;
import android.util.Log; import android.util.Log;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
public class DateTimeUtilUTest { public class DateTimeUtilUTest {
@Test @Test