cleanup & turn on looging in tests
This commit is contained in:
parent
9bfbbcf442
commit
6a83642c2e
|
@ -97,12 +97,6 @@ def allCommitted = { ->
|
|||
return stringBuilder.toString().isEmpty()
|
||||
}
|
||||
|
||||
tasks.matching { it instanceof Test }.all {
|
||||
testLogging.events = ["failed", "skipped", "started"]
|
||||
// testLogging.events = ["failed", "skipped", "started", "standard_out"] use to display stdout in travis
|
||||
testLogging.exceptionFormat = "full"
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
namespace 'info.nightscout.androidaps'
|
||||
|
|
|
@ -2,31 +2,31 @@ package info.nightscout.androidaps.plugins.general.autotune
|
|||
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.*
|
||||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.data.LocalInsulin
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.embedments.InterfaceIDs
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.database.entities.*
|
||||
import info.nightscout.androidaps.extensions.durationInMinutes
|
||||
import info.nightscout.androidaps.extensions.iobCalc
|
||||
import info.nightscout.androidaps.extensions.toJson
|
||||
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.general.autotune.data.ATProfile
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.Round
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Singleton
|
||||
open class AutotuneIob @Inject constructor(
|
||||
|
@ -59,24 +59,24 @@ open class AutotuneIob @Inject constructor(
|
|||
initializeTreatmentData(from - range(), to)
|
||||
initializeTempBasalData(from - range(), to, tunedProfile)
|
||||
initializeExtendedBolusData(from - range(), to, tunedProfile)
|
||||
Collections.sort(tempBasals) { o1: TemporaryBasal, o2: TemporaryBasal -> (o2.timestamp - o1.timestamp).toInt() }
|
||||
tempBasals.sortWith { o1: TemporaryBasal, o2: TemporaryBasal -> (o2.timestamp - o1.timestamp).toInt() }
|
||||
// Without Neutral TBR, Autotune Web will ignore iob for periods without TBR running
|
||||
addNeutralTempBasal(from - range(), to, tunedProfile)
|
||||
Collections.sort(nsTreatments) { o1: NsTreatment, o2: NsTreatment -> (o2.date - o1.date).toInt() }
|
||||
Collections.sort(boluses) { o1: Bolus, o2: Bolus -> (o2.timestamp - o1.timestamp).toInt() }
|
||||
log.debug("D/AutotunePlugin: Nb Treatments: " + nsTreatments.size + " Nb meals: " + meals.size)
|
||||
nsTreatments.sortWith { o1: NsTreatment, o2: NsTreatment -> (o2.date - o1.date).toInt() }
|
||||
this.boluses.sortWith { o1: Bolus, o2: Bolus -> (o2.timestamp - o1.timestamp).toInt() }
|
||||
aapsLogger.debug(LTag.AUTOTUNE, "Nb Treatments: " + nsTreatments.size + " Nb meals: " + meals.size)
|
||||
}
|
||||
|
||||
private fun initializeBgreadings(from: Long, to: Long) {
|
||||
glucose = repository.compatGetBgReadingsDataFromTime(from, to, false).blockingGet();
|
||||
glucose = repository.compatGetBgReadingsDataFromTime(from, to, false).blockingGet()
|
||||
}
|
||||
|
||||
//nsTreatment is used only for export data, meals is used in AutotunePrep
|
||||
private fun initializeTreatmentData(from: Long, to: Long) {
|
||||
val oldestBgDate = if (glucose.size > 0) glucose[glucose.size - 1].timestamp else from
|
||||
log.debug("AutotunePlugin Check BG date: BG Size: " + glucose.size + " OldestBG: " + dateUtil.dateAndTimeAndSecondsString(oldestBgDate) + " to: " + dateUtil.dateAndTimeAndSecondsString(to))
|
||||
val oldestBgDate = if (glucose.isNotEmpty()) glucose[glucose.size - 1].timestamp else from
|
||||
aapsLogger.debug(LTag.AUTOTUNE, "Check BG date: BG Size: " + glucose.size + " OldestBG: " + dateUtil.dateAndTimeAndSecondsString(oldestBgDate) + " to: " + dateUtil.dateAndTimeAndSecondsString(to))
|
||||
val tmpCarbs = repository.getCarbsDataFromTimeToTimeExpanded(from, to, false).blockingGet()
|
||||
log.debug("AutotunePlugin Nb treatments after query: " + tmpCarbs.size)
|
||||
aapsLogger.debug(LTag.AUTOTUNE, "Nb treatments after query: " + tmpCarbs.size)
|
||||
meals.clear()
|
||||
boluses.clear()
|
||||
var nbCarbs = 0
|
||||
|
@ -217,7 +217,7 @@ open class AutotuneIob @Inject constructor(
|
|||
tempBasals.add(newtb)
|
||||
nsTreatments.add(NsTreatment(newtb))
|
||||
splittedTimestamp += durationFilled
|
||||
splittedDuration = splittedDuration - durationFilled
|
||||
splittedDuration -= durationFilled
|
||||
val profile = profileFunction.getProfile(newtb.timestamp) ?:continue
|
||||
boluses.addAll(convertToBoluses(newtb, profile, tunedProfile.profile)) // required for correct iob calculation with oref0 algo
|
||||
}
|
||||
|
@ -377,8 +377,4 @@ open class AutotuneIob @Inject constructor(
|
|||
private fun log(message: String) {
|
||||
autotuneFS.atLog("[iob] $message")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(AutotunePlugin::class.java)
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import org.mockito.ArgumentMatchers.anyInt
|
|||
import org.mockito.ArgumentMatchers.anyString
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.invocation.InvocationOnMock
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
|
@ -52,7 +53,8 @@ open class TestBaseWithProfile : TestBase() {
|
|||
validProfileJSON = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"3\"}," +
|
||||
"{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," +
|
||||
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
|
||||
dateUtil = DateUtil(context)
|
||||
dateUtil = Mockito.spy(DateUtil(context))
|
||||
`when`(dateUtil.now()).thenReturn(1656358822000)
|
||||
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
|
||||
effectiveProfileSwitch = EffectiveProfileSwitch(
|
||||
timestamp = dateUtil.now(),
|
||||
|
|
|
@ -25,71 +25,74 @@ import java.io.File
|
|||
import java.util.*
|
||||
|
||||
class AutotuneCoreTest : TestBaseWithProfile() {
|
||||
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var autotuneFS: AutotuneFS
|
||||
@Mock lateinit var injector: HasAndroidInjector
|
||||
@Mock lateinit var activePlugin: ActivePlugin
|
||||
lateinit var autotuneCore: AutotuneCore
|
||||
var min5mCarbImpact = 0.0
|
||||
var autotuneMin = 0.0
|
||||
var autotuneMax = 0.0
|
||||
private lateinit var autotuneCore: AutotuneCore
|
||||
private var min5mCarbImpact = 0.0
|
||||
private var autotuneMin = 0.0
|
||||
private var autotuneMax = 0.0
|
||||
|
||||
@Before
|
||||
@Before
|
||||
fun initData() {
|
||||
autotuneCore = AutotuneCore(sp,autotuneFS)
|
||||
autotuneCore = AutotuneCore(sp, autotuneFS)
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+2"))
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@Test
|
||||
fun autotuneCoreTest1() { // Test if AutotuneCore with input files of OpenAPS categorisation gives correct ouput profile
|
||||
val prepjson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
fun autotuneCoreTest1() { // Test if AutotuneCore with input files of OpenAPS categorisation gives correct output profile
|
||||
val prepJson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
val inputProfileJson = File("src/test/res/autotune/test1/profile.pump.json").readText()
|
||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
val prep = PreppedGlucose(JSONObject(prepjson), dateUtil)
|
||||
val prep = PreppedGlucose(JSONObject(prepJson), dateUtil)
|
||||
|
||||
`when`(sp.getDouble(R.string.key_openapsama_autosens_max, 1.2)).thenReturn(autotuneMax)
|
||||
`when`(sp.getDouble(R.string.key_openapsama_autosens_min, 0.7)).thenReturn(autotuneMin)
|
||||
`when`(sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)).thenReturn(min5mCarbImpact)
|
||||
val OapsOutputProfileJson = File("src/test/res/autotune/test1/aapsorefprofile.json").readText()
|
||||
val OapsOutputProfile = atProfileFromOapsJson(JSONObject(OapsOutputProfileJson),dateUtil)
|
||||
val oapsOutputProfileJson = File("src/test/res/autotune/test1/aapsorefprofile.json").readText()
|
||||
val oapsOutputProfile = atProfileFromOapsJson(JSONObject(oapsOutputProfileJson), dateUtil)
|
||||
val outProfile = autotuneCore.tuneAllTheThings(prep, inputProfile, inputProfile)
|
||||
OapsOutputProfile?.let {
|
||||
Assert.assertEquals(OapsOutputProfile.isf, outProfile.isf, 0.0)
|
||||
Assert.assertEquals(OapsOutputProfile.ic, outProfile.ic, 0.0)
|
||||
oapsOutputProfile?.let {
|
||||
Assert.assertEquals(oapsOutputProfile.isf, outProfile.isf, 0.0)
|
||||
Assert.assertEquals(oapsOutputProfile.ic, outProfile.ic, 0.0)
|
||||
for (i in 0..23)
|
||||
Assert.assertEquals(OapsOutputProfile.basal[i], outProfile.basal[i], 0.0)
|
||||
Assert.assertEquals(oapsOutputProfile.basal[i], outProfile.basal[i], 0.0)
|
||||
}
|
||||
?:Assert.fail()
|
||||
?: Assert.fail()
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@Test
|
||||
fun autotuneCoreTest4() { // Test if limiting modification with Min Max Autosens parameter works (18h on basal and on ISF value)
|
||||
val prepjson = File("src/test/res/autotune/test4/autotune.2022-05-30.json").readText()
|
||||
val prepJson = File("src/test/res/autotune/test4/autotune.2022-05-30.json").readText()
|
||||
val inputProfileJson = File("src/test/res/autotune/test4/profile.2022-05-30.json").readText()
|
||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
val pumpProfileJson = File("src/test/res/autotune/test4/profile.pump.json").readText()
|
||||
val pumpProfile = atProfileFromOapsJson(JSONObject(pumpProfileJson), dateUtil)!!
|
||||
val prep = PreppedGlucose(JSONObject(prepjson), dateUtil)
|
||||
val prep = PreppedGlucose(JSONObject(prepJson), dateUtil)
|
||||
`when`(sp.getDouble(R.string.key_openapsama_autosens_max, 1.2)).thenReturn(autotuneMax)
|
||||
`when`(sp.getDouble(R.string.key_openapsama_autosens_min, 0.7)).thenReturn(autotuneMin)
|
||||
`when`(sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)).thenReturn(min5mCarbImpact)
|
||||
val OapsOutputProfileJson = File("src/test/res/autotune/test4/newprofile.2022-05-30.json").readText()
|
||||
val OapsOutputProfile = atProfileFromOapsJson(JSONObject(OapsOutputProfileJson),dateUtil)
|
||||
val oapsOutputProfileJson = File("src/test/res/autotune/test4/newprofile.2022-05-30.json").readText()
|
||||
val oapsOutputProfile = atProfileFromOapsJson(JSONObject(oapsOutputProfileJson), dateUtil)
|
||||
val outProfile = autotuneCore.tuneAllTheThings(prep, inputProfile, pumpProfile)
|
||||
OapsOutputProfile?.let {
|
||||
Assert.assertEquals(OapsOutputProfile.isf, outProfile.isf, 0.0)
|
||||
Assert.assertEquals(OapsOutputProfile.ic, outProfile.ic, 0.0)
|
||||
oapsOutputProfile?.let {
|
||||
Assert.assertEquals(oapsOutputProfile.isf, outProfile.isf, 0.0)
|
||||
Assert.assertEquals(oapsOutputProfile.ic, outProfile.ic, 0.0)
|
||||
for (i in 0..23)
|
||||
Assert.assertEquals(OapsOutputProfile.basal[i], outProfile.basal[i], 0.0)
|
||||
Assert.assertEquals(oapsOutputProfile.basal[i], outProfile.basal[i], 0.0)
|
||||
}
|
||||
?:Assert.fail()
|
||||
?: Assert.fail()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OpenAPS profile for Autotune only have one ISF value and one IC value
|
||||
*/
|
||||
fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): ATProfile? {
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): ATProfile? {
|
||||
try {
|
||||
min5mCarbImpact = JsonHelper.safeGetDoubleAllowNull(jsonObject, "min_5m_carbimpact") ?: return null
|
||||
autotuneMin = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_min") ?: return null
|
||||
|
@ -104,13 +107,13 @@ class AutotuneCoreTest : TestBaseWithProfile() {
|
|||
val isfBlocks = ArrayList<Block>(1).also {
|
||||
val isfJsonArray = isfJson.getJSONArray("sensitivities")
|
||||
val value = isfJsonArray.getJSONObject(0).getDouble("sensitivity")
|
||||
it.add(0,Block((T.hours(24).secs()) * 1000L, value))
|
||||
it.add(0, Block((T.hours(24).secs()) * 1000L, value))
|
||||
}
|
||||
val icBlocks = ArrayList<Block>(1).also {
|
||||
val value = jsonObject.getDouble("carb_ratio")
|
||||
it.add(0,Block((T.hours(24).secs()) * 1000L, value))
|
||||
it.add(0, Block((T.hours(24).secs()) * 1000L, value))
|
||||
}
|
||||
val basalBlocks = blockFromJsonArray(jsonObject.getJSONArray("basalprofile"), dateUtil)
|
||||
val basalBlocks = blockFromJsonArray(jsonObject.getJSONArray("basalprofile"))
|
||||
?: return null
|
||||
val targetBlocks = ArrayList<TargetBlock>(1).also {
|
||||
it.add(0, TargetBlock((T.hours(24).secs()) * 1000L, 100.0, 100.0))
|
||||
|
@ -126,14 +129,13 @@ class AutotuneCoreTest : TestBaseWithProfile() {
|
|||
timeZone = timezone,
|
||||
dia = dia
|
||||
)
|
||||
return ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil}
|
||||
return ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil }
|
||||
} catch (ignored: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun blockFromJsonArray(jsonArray: JSONArray?, dateUtil: DateUtil): List<Block>? {
|
||||
private fun blockFromJsonArray(jsonArray: JSONArray?): List<Block>? {
|
||||
val size = jsonArray?.length() ?: return null
|
||||
val ret = ArrayList<Block>(size)
|
||||
try {
|
||||
|
|
|
@ -29,20 +29,20 @@ import org.mockito.Mock
|
|||
import org.mockito.Mockito.`when`
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class AutotunePrepTest : TestBaseWithProfile() {
|
||||
|
||||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var autotuneFS: AutotuneFS
|
||||
@Mock lateinit var injector: HasAndroidInjector
|
||||
@Mock lateinit var activePlugin: ActivePlugin
|
||||
@Mock lateinit var repository: AppRepository
|
||||
lateinit var autotunePrep: AutotunePrep
|
||||
lateinit var autotuneIob: TestAutotuneIob
|
||||
var min5mCarbImpact = 0.0
|
||||
var autotuneMin = 0.0
|
||||
var autotuneMax = 0.0
|
||||
var startDayTime = 0L
|
||||
private lateinit var autotunePrep: AutotunePrep
|
||||
private lateinit var autotuneIob: TestAutotuneIob
|
||||
private var min5mCarbImpact = 0.0
|
||||
private var autotuneMin = 0.0
|
||||
private var autotuneMax = 0.0
|
||||
private var startDayTime = 0L
|
||||
|
||||
@Before
|
||||
fun initData() {
|
||||
|
@ -52,17 +52,17 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
@Test
|
||||
fun autotunePrepTest1() { // Test if categorisation with standard treatments with carbs is Ok
|
||||
val inputIobJson = File("src/test/res/autotune/test1/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
||||
val iobOapsCalcul = buildIobOaps(JSONArray(inputIobJson))
|
||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalcul)
|
||||
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalculation)
|
||||
autotunePrep = AutotunePrep(sp, dateUtil, autotuneFS, autotuneIob)
|
||||
val inputProfileJson = File("src/test/res/autotune/test1/profile.pump.json").readText()
|
||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
val prepjson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
val oapsPreppedGlucose = PreppedGlucose(JSONObject(prepjson), dateUtil) //prep data calculated by OpenAPS autotune
|
||||
val prepJson = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
val oapsPreppedGlucose = PreppedGlucose(JSONObject(prepJson), dateUtil) //prep data calculated by OpenAPS autotune
|
||||
val oapsEntriesJson = File("src/test/res/autotune/test1/aaps-entries.2022-05-21.json").readText()
|
||||
autotuneIob.glucose = buildGlucose(JSONArray(oapsEntriesJson))
|
||||
autotuneIob.glucose = buildGlucose(JSONArray(oapsEntriesJson))
|
||||
val oapsTreatmentsJson = File("src/test/res/autotune/test1/aaps-treatments.2022-05-21.json").readText()
|
||||
autotuneIob.meals = buildMeals(JSONArray(oapsTreatmentsJson)) //Only meals is used in unit test, Insulin only used for iob calculation
|
||||
autotuneIob.meals = buildMeals(JSONArray(oapsTreatmentsJson)) //Only meals is used in unit test, Insulin only used for iob calculation
|
||||
autotuneIob.boluses = buildBoluses(oapsPreppedGlucose) //Values from oapsPrepData because linked to iob calculation method for TBR
|
||||
`when`(sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)).thenReturn(min5mCarbImpact)
|
||||
`when`(sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)).thenReturn(false)
|
||||
|
@ -88,21 +88,20 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun autotunePrepTest2() { // Test if categorisation without carbs (full UAM) and categorize UAM as basal false is Ok
|
||||
val inputIobJson = File("src/test/res/autotune/test2/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
||||
val iobOapsCalcul = buildIobOaps(JSONArray(inputIobJson))
|
||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalcul)
|
||||
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalculation)
|
||||
autotunePrep = AutotunePrep(sp, dateUtil, autotuneFS, autotuneIob)
|
||||
val inputProfileJson = File("src/test/res/autotune/test2/profile.pump.json").readText()
|
||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
val prepjson = File("src/test/res/autotune/test2/autotune.2022-05-21.json").readText()
|
||||
val oapsPreppedGlucose = PreppedGlucose(JSONObject(prepjson), dateUtil) //prep data calculated by OpenAPS autotune
|
||||
val prepJson = File("src/test/res/autotune/test2/autotune.2022-05-21.json").readText()
|
||||
val oapsPreppedGlucose = PreppedGlucose(JSONObject(prepJson), dateUtil) //prep data calculated by OpenAPS autotune
|
||||
val oapsEntriesJson = File("src/test/res/autotune/test2/aaps-entries.2022-05-21.json").readText()
|
||||
autotuneIob.glucose = buildGlucose(JSONArray(oapsEntriesJson))
|
||||
autotuneIob.glucose = buildGlucose(JSONArray(oapsEntriesJson))
|
||||
val oapsTreatmentsJson = File("src/test/res/autotune/test2/aaps-treatments.2022-05-21.json").readText()
|
||||
autotuneIob.meals = buildMeals(JSONArray(oapsTreatmentsJson)) //Only meals is used in unit test, Insulin only used for iob calculation
|
||||
autotuneIob.meals = buildMeals(JSONArray(oapsTreatmentsJson)) //Only meals is used in unit test, Insulin only used for iob calculation
|
||||
autotuneIob.boluses = buildBoluses(oapsPreppedGlucose) //Values from oapsPrepData because linked to iob calculation method for TBR
|
||||
`when`(sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)).thenReturn(min5mCarbImpact)
|
||||
`when`(sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)).thenReturn(false) // CategorizeUAM as Basal = False
|
||||
|
@ -131,17 +130,17 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
@Test
|
||||
fun autotunePrepTest3() { // Test if categorisation without carbs (full UAM) and categorize UAM as basal true is Ok
|
||||
val inputIobJson = File("src/test/res/autotune/test3/oaps-iobCalc.2022-05-21.json").readText() //json files build with iob/activity calculated by OAPS
|
||||
val iobOapsCalcul = buildIobOaps(JSONArray(inputIobJson))
|
||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalcul)
|
||||
val iobOapsCalculation = buildIobOaps(JSONArray(inputIobJson))
|
||||
autotuneIob = TestAutotuneIob(aapsLogger, repository, profileFunction, sp, dateUtil, activePlugin, autotuneFS, iobOapsCalculation)
|
||||
autotunePrep = AutotunePrep(sp, dateUtil, autotuneFS, autotuneIob)
|
||||
val inputProfileJson = File("src/test/res/autotune/test3/profile.pump.json").readText()
|
||||
val inputProfile = atProfileFromOapsJson(JSONObject(inputProfileJson), dateUtil)!!
|
||||
val prepjson = File("src/test/res/autotune/test3/autotune.2022-05-21.json").readText()
|
||||
val oapsPreppedGlucose = PreppedGlucose(JSONObject(prepjson), dateUtil) //prep data calculated by OpenAPS autotune
|
||||
val prepJson = File("src/test/res/autotune/test3/autotune.2022-05-21.json").readText()
|
||||
val oapsPreppedGlucose = PreppedGlucose(JSONObject(prepJson), dateUtil) //prep data calculated by OpenAPS autotune
|
||||
val oapsEntriesJson = File("src/test/res/autotune/test3/aaps-entries.2022-05-21.json").readText()
|
||||
autotuneIob.glucose = buildGlucose(JSONArray(oapsEntriesJson))
|
||||
autotuneIob.glucose = buildGlucose(JSONArray(oapsEntriesJson))
|
||||
val oapsTreatmentsJson = File("src/test/res/autotune/test3/aaps-treatments.2022-05-21.json").readText()
|
||||
autotuneIob.meals = buildMeals(JSONArray(oapsTreatmentsJson)) //Only meals is used in unit test, Insulin only used for iob calculation
|
||||
autotuneIob.meals = buildMeals(JSONArray(oapsTreatmentsJson)) //Only meals is used in unit test, Insulin only used for iob calculation
|
||||
autotuneIob.boluses = buildBoluses(oapsPreppedGlucose) //Values from oapsPrepData because linked to iob calculation method for TBR
|
||||
`when`(sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, 3.0)).thenReturn(min5mCarbImpact)
|
||||
`when`(sp.getBoolean(R.string.key_autotune_categorize_uam_as_basal, false)).thenReturn(true) // CategorizeUAM as Basal = True
|
||||
|
@ -170,7 +169,8 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
/*************************************************************************************************************************************************************************************
|
||||
* OpenAPS profile for Autotune only have one ISF value and one IC value
|
||||
*/
|
||||
fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): ATProfile? {
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): ATProfile? {
|
||||
try {
|
||||
min5mCarbImpact = JsonHelper.safeGetDoubleAllowNull(jsonObject, "min_5m_carbimpact") ?: return null
|
||||
autotuneMin = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_min") ?: return null
|
||||
|
@ -185,13 +185,13 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
val isfBlocks = ArrayList<Block>(1).also {
|
||||
val isfJsonArray = isfJson.getJSONArray("sensitivities")
|
||||
val value = isfJsonArray.getJSONObject(0).getDouble("sensitivity")
|
||||
it.add(0,Block((T.hours(24).secs()) * 1000L, value))
|
||||
it.add(0, Block((T.hours(24).secs()) * 1000L, value))
|
||||
}
|
||||
val icBlocks = ArrayList<Block>(1).also {
|
||||
val value = jsonObject.getDouble("carb_ratio")
|
||||
it.add(0,Block((T.hours(24).secs()) * 1000L, value))
|
||||
it.add(0, Block((T.hours(24).secs()) * 1000L, value))
|
||||
}
|
||||
val basalBlocks = blockFromJsonArray(jsonObject.getJSONArray("basalprofile"), dateUtil)
|
||||
val basalBlocks = blockFromJsonArray(jsonObject.getJSONArray("basalprofile"))
|
||||
?: return null
|
||||
val targetBlocks = ArrayList<TargetBlock>(1).also {
|
||||
it.add(0, TargetBlock((T.hours(24).secs()) * 1000L, 100.0, 100.0))
|
||||
|
@ -207,14 +207,13 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
timeZone = timezone,
|
||||
dia = dia
|
||||
)
|
||||
return ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil}
|
||||
return ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil }
|
||||
} catch (ignored: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun blockFromJsonArray(jsonArray: JSONArray?, dateUtil: DateUtil): List<Block>? {
|
||||
private fun blockFromJsonArray(jsonArray: JSONArray?): List<Block>? {
|
||||
val size = jsonArray?.length() ?: return null
|
||||
val ret = ArrayList<Block>(size)
|
||||
try {
|
||||
|
@ -238,19 +237,19 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
return ret
|
||||
}
|
||||
|
||||
fun buildBoluses(preppedGlucose: PreppedGlucose): ArrayList<Bolus> { //if categorization is correct then I return for dose function the crInsulin calculated in Oaps
|
||||
private fun buildBoluses(preppedGlucose: PreppedGlucose): ArrayList<Bolus> { //if categorization is correct then I return for dose function the crInsulin calculated in Oaps
|
||||
val boluses: ArrayList<Bolus> = ArrayList()
|
||||
try {
|
||||
for (i in preppedGlucose.crData.indices) {
|
||||
boluses.add(
|
||||
Bolus(
|
||||
timestamp = preppedGlucose.crData[i].crEndTime,
|
||||
amount = preppedGlucose.crData[i].crInsulin,
|
||||
type = Bolus.Type.NORMAL
|
||||
)
|
||||
// try {
|
||||
for (i in preppedGlucose.crData.indices) {
|
||||
boluses.add(
|
||||
Bolus(
|
||||
timestamp = preppedGlucose.crData[i].crEndTime,
|
||||
amount = preppedGlucose.crData[i].crInsulin,
|
||||
type = Bolus.Type.NORMAL
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) { }
|
||||
)
|
||||
}
|
||||
// } catch (e: Exception) { }
|
||||
if (boluses.size == 0) //Add at least one insulin treatment for tests to avoid return null in categorization
|
||||
boluses.add(
|
||||
Bolus(
|
||||
|
@ -262,41 +261,41 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
return boluses
|
||||
}
|
||||
|
||||
fun buildMeals(jsonArray: JSONArray): ArrayList<Carbs> {
|
||||
private fun buildMeals(jsonArray: JSONArray): ArrayList<Carbs> {
|
||||
val list: ArrayList<Carbs> = ArrayList()
|
||||
try {
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val value = JsonHelper.safeGetDouble(json, "carbs", 0.0)
|
||||
val timestamp = JsonHelper.safeGetLong(json, "date")
|
||||
if (value > 0.0 && timestamp > startDayTime) {
|
||||
list.add(Carbs(timestamp=timestamp, amount = value, duration = 0))
|
||||
}
|
||||
// try {
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val value = JsonHelper.safeGetDouble(json, "carbs", 0.0)
|
||||
val timestamp = JsonHelper.safeGetLong(json, "date")
|
||||
if (value > 0.0 && timestamp > startDayTime) {
|
||||
list.add(Carbs(timestamp = timestamp, amount = value, duration = 0))
|
||||
}
|
||||
} catch (e: Exception) { }
|
||||
}
|
||||
// } catch (e: Exception) { }
|
||||
return list
|
||||
}
|
||||
|
||||
fun buildGlucose(jsonArray: JSONArray): List<GlucoseValue> {
|
||||
private fun buildGlucose(jsonArray: JSONArray): List<GlucoseValue> {
|
||||
val list: ArrayList<GlucoseValue> = ArrayList()
|
||||
try {
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val value = JsonHelper.safeGetDouble(json, "sgv")
|
||||
val timestamp = JsonHelper.safeGetLong(json, "date")
|
||||
list.add(GlucoseValue(raw = value, noise = 0.0, value = value, timestamp = timestamp, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
}
|
||||
} catch (e: Exception) { }
|
||||
// try {
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val value = JsonHelper.safeGetDouble(json, "sgv")
|
||||
val timestamp = JsonHelper.safeGetLong(json, "date")
|
||||
list.add(GlucoseValue(raw = value, noise = 0.0, value = value, timestamp = timestamp, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
}
|
||||
// } catch (e: Exception) { }
|
||||
if (list.size > 0)
|
||||
startDayTime = list[list.size-1].timestamp
|
||||
startDayTime = list[list.size - 1].timestamp
|
||||
return list
|
||||
}
|
||||
|
||||
fun buildIobOaps(jsonArray: JSONArray): ArrayList<IobTotal> { //if categorization is correct then I return for dose function the crInsulin calculated in Oaps
|
||||
private fun buildIobOaps(jsonArray: JSONArray): ArrayList<IobTotal> { //if categorization is correct then I return for dose function the crInsulin calculated in Oaps
|
||||
val list: ArrayList<IobTotal> = ArrayList()
|
||||
for (index in 0 until jsonArray.length()) {
|
||||
val json = jsonArray.getJSONObject(index)
|
||||
val time = JsonHelper.safeGetLong(json,"date")
|
||||
val time = JsonHelper.safeGetLong(json, "date")
|
||||
val iob = JsonHelper.safeGetDouble(json, "iob")
|
||||
val activity = JsonHelper.safeGetDouble(json, "activity")
|
||||
val iobTotal = IobTotal(time)
|
||||
|
@ -315,7 +314,7 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
val dateUtil: DateUtil,
|
||||
val activePlugin: ActivePlugin,
|
||||
autotuneFS: AutotuneFS,
|
||||
val iobOapsCalcul: ArrayList<IobTotal>
|
||||
private val iobOapsCalculation: ArrayList<IobTotal>
|
||||
) : AutotuneIob(
|
||||
aapsLogger,
|
||||
repository,
|
||||
|
@ -325,9 +324,10 @@ class AutotunePrepTest : TestBaseWithProfile() {
|
|||
activePlugin,
|
||||
autotuneFS
|
||||
) {
|
||||
|
||||
override fun getIOB(time: Long, localInsulin: LocalInsulin): IobTotal {
|
||||
var bolusIob = IobTotal(time)
|
||||
iobOapsCalcul.forEach {
|
||||
val bolusIob = IobTotal(time)
|
||||
iobOapsCalculation.forEach {
|
||||
if (it.time == time)
|
||||
return it
|
||||
}
|
||||
|
|
|
@ -1,35 +1,48 @@
|
|||
package info.nightscout.androidaps.plugins.general.autotune
|
||||
|
||||
import android.content.Context
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.androidaps.plugins.general.autotune.data.*
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.androidaps.plugins.general.autotune.data.BGDatum
|
||||
import info.nightscout.androidaps.plugins.general.autotune.data.CRDatum
|
||||
import info.nightscout.androidaps.plugins.general.autotune.data.PreppedGlucose
|
||||
import org.json.JSONObject
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import java.io.File
|
||||
|
||||
class PreppedGlucoseTest : TestBase() {
|
||||
@Mock lateinit var context: Context
|
||||
lateinit var dateUtil: DateUtil
|
||||
lateinit var prep1: PreppedGlucose
|
||||
lateinit var prepjson1: String
|
||||
class PreppedGlucoseTest : TestBaseWithProfile() {
|
||||
|
||||
private lateinit var prep1: PreppedGlucose
|
||||
private lateinit var prepJson1: String
|
||||
|
||||
@Before
|
||||
fun initData() {
|
||||
dateUtil = DateUtil(context)
|
||||
prepjson1 = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
prep1 = PreppedGlucose(JSONObject(prepjson1), dateUtil)
|
||||
prepJson1 = File("src/test/res/autotune/test1/autotune.2022-05-21.json").readText()
|
||||
prep1 = PreppedGlucose(JSONObject(prepJson1), dateUtil)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun preppedGlucoseLoadTest() { // Test if load from file of OpenAPS categorisation is Ok
|
||||
val crData0 = CRDatum(JSONObject("{\"CRInitialIOB\":13.594,\"CRInitialBG\":123,\"CRInitialCarbTime\":\"2022-05-21T07:54:09.000Z\",\"CREndIOB\":-0.155,\"CREndBG\":98,\"CREndTime\":\"2022-05-21T11:19:08.000Z\",\"CRCarbs\":70,\"CRInsulin\":-2.13}"), dateUtil)
|
||||
val csfDataEnd = BGDatum(JSONObject("{\"device\":\"AndroidAPS-DexcomG6\",\"date\":1653176050000,\"dateString\":\"2022-05-21T23:34:10.000Z\",\"isValid\":true,\"sgv\":127,\"direction\":\"Flat\",\"type\":\"sgv\",\"_id\":\"6289771371a363000480abc1\",\"glucose\":127,\"avgDelta\":\"2.50\",\"BGI\":-2.93,\"deviation\":\"5.43\",\"mealCarbs\":0,\"mealAbsorption\":\"end\"}"), dateUtil)
|
||||
val isfData0 = BGDatum(JSONObject("{\"device\":\"AndroidAPS-DexcomG6\",\"date\":1653108249000,\"dateString\":\"2022-05-21T04:44:09.000Z\",\"isValid\":true,\"sgv\":123,\"direction\":\"FortyFiveDown\",\"type\":\"sgv\",\"_id\":\"62886e2919e2e60004989bba\",\"glucose\":123,\"avgDelta\":\"-7.50\",\"BGI\":-7.59,\"deviation\":\"0.09\"}"), dateUtil)
|
||||
val basalDataEnd = BGDatum(JSONObject("{\"device\":\"AndroidAPS-DexcomG6\",\"date\":1653180549000,\"dateString\":\"2022-05-22T00:49:09.000Z\",\"isValid\":true,\"sgv\":121,\"direction\":\"FortyFiveDown\",\"type\":\"sgv\",\"_id\":\"628988a3da46aa0004d1e0f5\",\"glucose\":121,\"avgDelta\":\"-5.25\",\"BGI\":-3.32,\"deviation\":\"-1.93\"}"), dateUtil)
|
||||
val crData0 =
|
||||
CRDatum(
|
||||
JSONObject("{\"CRInitialIOB\":13.594,\"CRInitialBG\":123,\"CRInitialCarbTime\":\"2022-05-21T07:54:09.000Z\",\"CREndIOB\":-0.155,\"CREndBG\":98,\"CREndTime\":\"2022-05-21T11:19:08.000Z\",\"CRCarbs\":70,\"CRInsulin\":-2.13}"),
|
||||
dateUtil
|
||||
)
|
||||
val csfDataEnd =
|
||||
BGDatum(
|
||||
JSONObject("{\"device\":\"AndroidAPS-DexcomG6\",\"date\":1653176050000,\"dateString\":\"2022-05-21T23:34:10.000Z\",\"isValid\":true,\"sgv\":127,\"direction\":\"Flat\",\"type\":\"sgv\",\"_id\":\"6289771371a363000480abc1\",\"glucose\":127,\"avgDelta\":\"2.50\",\"BGI\":-2.93,\"deviation\":\"5.43\",\"mealCarbs\":0,\"mealAbsorption\":\"end\"}"),
|
||||
dateUtil
|
||||
)
|
||||
val isfData0 =
|
||||
BGDatum(
|
||||
JSONObject("{\"device\":\"AndroidAPS-DexcomG6\",\"date\":1653108249000,\"dateString\":\"2022-05-21T04:44:09.000Z\",\"isValid\":true,\"sgv\":123,\"direction\":\"FortyFiveDown\",\"type\":\"sgv\",\"_id\":\"62886e2919e2e60004989bba\",\"glucose\":123,\"avgDelta\":\"-7.50\",\"BGI\":-7.59,\"deviation\":\"0.09\"}"),
|
||||
dateUtil
|
||||
)
|
||||
val basalDataEnd =
|
||||
BGDatum(
|
||||
JSONObject("{\"device\":\"AndroidAPS-DexcomG6\",\"date\":1653180549000,\"dateString\":\"2022-05-22T00:49:09.000Z\",\"isValid\":true,\"sgv\":121,\"direction\":\"FortyFiveDown\",\"type\":\"sgv\",\"_id\":\"628988a3da46aa0004d1e0f5\",\"glucose\":121,\"avgDelta\":\"-5.25\",\"BGI\":-3.32,\"deviation\":\"-1.93\"}"),
|
||||
dateUtil
|
||||
)
|
||||
Assert.assertEquals(3, prep1.crData.size)
|
||||
Assert.assertTrue(crData0.equals(prep1.crData[0]))
|
||||
Assert.assertTrue(csfDataEnd.equals(prep1.csfGlucoseData[prep1.csfGlucoseData.size - 1]))
|
||||
|
|
|
@ -15,6 +15,13 @@ dependencies {
|
|||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
}
|
||||
|
||||
tasks.matching { it instanceof Test }.all {
|
||||
//testLogging.events = ["failed", "skipped", "started"]
|
||||
// use to display stdout in travis
|
||||
testLogging.events = ["failed", "skipped", "started", "standard_out"]
|
||||
testLogging.exceptionFormat = "full"
|
||||
}
|
||||
|
||||
android {
|
||||
testOptions {
|
||||
unitTests {
|
||||
|
|
Loading…
Reference in a new issue