Trigger tests

This commit is contained in:
Milos Kozak 2020-03-11 00:03:59 +01:00
parent 99aec40534
commit e812dd9437
9 changed files with 258 additions and 300 deletions

View file

@ -21,8 +21,6 @@ import java.util.*
class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) { class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
var list: MutableList<Trigger> = ArrayList() var list: MutableList<Trigger> = ArrayList()
private var connectorType: Type = Type.AND private var connectorType: Type = Type.AND
// TODO move to TriggerConnector
//var connector: TriggerConnector = TriggerConnector(injector, TriggerConnector.Type.AND)
enum class Type { enum class Type {
AND, OR, XOR; AND, OR, XOR;

View file

@ -4,10 +4,10 @@ import com.google.common.base.Optional
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
// Used for instantiation of other triggers only // Used for instantiation of other triggers only
class TriggerDummy(injector: HasAndroidInjector) : Trigger(injector) { class TriggerDummy(injector: HasAndroidInjector, val shouldRun: Boolean = false) : Trigger(injector) {
override fun shouldRun(): Boolean { override fun shouldRun(): Boolean {
throw NotImplementedError("An operation is not implemented") return shouldRun
} }
override fun toJSON(): String { override fun toJSON(): String {
@ -23,7 +23,7 @@ class TriggerDummy(injector: HasAndroidInjector) : Trigger(injector) {
} }
override fun friendlyDescription(): String { override fun friendlyDescription(): String {
throw NotImplementedError("An operation is not implemented") return "TriggerDummy"
} }
override fun icon(): Optional<Int?> { override fun icon(): Optional<Int?> {

View file

@ -1,45 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable;
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnectorTest;
@RunWith(PowerMockRunner.class)
@PrepareForTest({})
public class AutomationEventTest {
@Test
public void testCloneEvent() throws CloneNotSupportedException {
// create test object
AutomationEvent event = new AutomationEvent();
event.setTitle("Test");
event.setTrigger(Trigger.instantiate(TriggerConnectorTest.oneItem));
event.addAction(new ActionLoopEnable());
// export to json
final String eventJsonExpected = "{\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\",\"title\":\"Test\",\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}";
Assert.assertEquals(eventJsonExpected, event.toJSON());
// clone
AutomationEvent clone = new AutomationEvent().fromJSON(eventJsonExpected);
// check title
Assert.assertEquals(event.getTitle(), clone.getTitle());
// check trigger
Assert.assertNotNull(clone.getTrigger());
Assert.assertFalse(event.getTrigger() == clone.getTrigger()); // not the same object reference
Assert.assertEquals(event.getTrigger().getClass(), clone.getTrigger().getClass());
Assert.assertEquals(event.getTrigger().toJSON(), clone.getTrigger().toJSON());
// check action
Assert.assertEquals(1, clone.getActions().size());
Assert.assertFalse(event.getActions() == clone.getActions()); // not the same object reference
Assert.assertEquals(clone.toJSON(), clone.toJSON());
}
}

View file

@ -0,0 +1,73 @@
package info.nightscout.androidaps.plugins.general.automation
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.TestBase
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnectorTest
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDummy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import org.json.JSONObject
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
class AutomationEventTest : TestBase() {
@Mock lateinit var aapsLogger: AAPSLogger
@Mock lateinit var loopPlugin: LoopPlugin
@Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var configBuilderPlugin: ConfigBuilderPlugin
var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector {
if (it is AutomationEvent) {
it.aapsLogger = aapsLogger
}
if (it is ActionLoopEnable) {
it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper
it.configBuilderPlugin = configBuilderPlugin
it.rxBus = RxBusWrapper()
}
}
}
@Test
fun testCloneEvent() {
// create test object
val event = AutomationEvent(injector)
event.title = "Test"
event.trigger = TriggerDummy(injector).instantiate(JSONObject(TriggerConnectorTest.oneItem))
?: throw Exception()
event.addAction(ActionLoopEnable(injector))
// export to json
val eventJsonExpected = "{\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\",\"title\":\"Test\",\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}"
Assert.assertEquals(eventJsonExpected, event.toJSON())
// clone
val clone = AutomationEvent(injector).fromJSON(eventJsonExpected)
// check title
Assert.assertEquals(event.title, clone.title)
// check trigger
Assert.assertNotNull(clone.trigger)
Assert.assertFalse(event.trigger === clone.trigger) // not the same object reference
Assert.assertEquals(event.trigger.javaClass, clone.trigger.javaClass)
Assert.assertEquals(event.trigger.toJSON(), clone.trigger.toJSON())
// check action
Assert.assertEquals(1, clone.actions.size.toLong())
Assert.assertFalse(event.actions === clone.actions) // not the same object reference
Assert.assertEquals(clone.toJSON(), clone.toJSON())
}
}

View file

@ -1,138 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.plugins.general.automation.dialogs.TriggerListAdapter;
import info.nightscout.androidaps.plugins.general.automation.triggers.DummyTrigger;
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
@RunWith(PowerMockRunner.class)
@PrepareForTest({})
public class ComposeTriggerTest {
@Test
public void testTriggerList() {
TriggerConnector root = new TriggerConnector();
// add some triggers
Trigger t0 = new DummyTrigger();
root.add(t0);
Trigger t1 = new DummyTrigger();
root.add(t1);
Trigger t2 = new DummyTrigger();
root.add(t2);
Assert.assertEquals(3, root.size());
Assert.assertEquals(t0, root.get(0));
Assert.assertEquals(t1, root.get(1));
Assert.assertEquals(t2, root.get(2));
// remove a trigger
root.remove(t1);
Assert.assertEquals(2, root.size());
Assert.assertEquals(t0, root.get(0));
Assert.assertEquals(t2, root.get(1));
}
@Test
public void testChangeConnector() {
// initialize scenario
TriggerConnector root = new TriggerConnector(TriggerConnector.Type.AND);
Trigger[] t = new Trigger[4];
for (int i = 0; i < t.length; ++i) {
t[i] = new DummyTrigger();
root.add(t[i]);
}
Assert.assertEquals(4, root.size());
// change connector of t1,t2 from "and" to "or"
Assert.assertEquals(root, t[2].getConnector());
TriggerListAdapter.changeConnector(null, t[2], t[2].getConnector(), TriggerConnector.Type.OR);
Assert.assertEquals(3, root.size());
Assert.assertEquals(t[0], root.get(0));
Assert.assertEquals(t[3], root.get(2));
Assert.assertTrue(root.get(1) instanceof TriggerConnector);
TriggerConnector newConnector = (TriggerConnector) root.get(1);
Assert.assertEquals(2, newConnector.size());
Assert.assertEquals(t[1], newConnector.get(0));
Assert.assertEquals(t[2], newConnector.get(1));
// undo
Assert.assertEquals(newConnector, t[2].getConnector());
TriggerListAdapter.changeConnector(null, t[2], t[2].getConnector(), TriggerConnector.Type.AND);
Assert.assertEquals(4, root.size());
for (int i = 0; i < 4; ++i) {
Assert.assertEquals(t[i], root.get(i));
}
}
@Test
public void testConnectorSimplify() {
// initialize scenario
/*
* parent
* -> child
* -> t0
* -> t1
*/
TriggerConnector parent = new TriggerConnector(TriggerConnector.Type.AND);
TriggerConnector child = new TriggerConnector(TriggerConnector.Type.AND);
Trigger t0 = new DummyTrigger();
Trigger t1 = new DummyTrigger();
child.add(t0);
child.add(t1);
parent.add(child);
Assert.assertEquals(1, parent.size());
Assert.assertEquals(child, parent.get(0));
Assert.assertEquals(2, child.size());
Assert.assertEquals(t0, child.get(0));
Assert.assertEquals(t1, child.get(1));
// simplify
parent.simplify();
/*
* parent
* -> t0
* -> t1
*/
Assert.assertEquals(2, parent.size());
Assert.assertEquals(t0, parent.get(0));
Assert.assertEquals(t1, parent.get(1));
// add a new child at position 1
/*
* parent
* -> t0
* -> newChild
* -> t2
* -> t1
*/
TriggerConnector newChild = new TriggerConnector(TriggerConnector.Type.AND);
Trigger t2 = new DummyTrigger();
newChild.add(t2);
parent.add(1, newChild);
// simplify
parent.simplify();
/*
* parent
* -> t0
* -> t2
* -> t1
*/
Assert.assertEquals(3, parent.size());
Assert.assertEquals(t0, parent.get(0));
Assert.assertEquals(t2, parent.get(1));
Assert.assertEquals(t1, parent.get(2));
}
}

View file

@ -0,0 +1,54 @@
package info.nightscout.androidaps.plugins.general.automation
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.TestBase
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDummy
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
@PrepareForTest
class ComposeTriggerTest : TestBase() {
var injector: HasAndroidInjector = HasAndroidInjector { AndroidInjector { } }
@Test fun testTriggerList() {
val root = TriggerConnector(injector)
// add some triggers
val t0: Trigger = TriggerDummy(injector)
root.list.add(t0)
val t1: Trigger = TriggerDummy(injector)
root.list.add(t1)
val t2: Trigger = TriggerDummy(injector)
root.list.add(t2)
Assert.assertEquals(3, root.size())
Assert.assertEquals(t0, root.list[0])
Assert.assertEquals(t1, root.list[1])
Assert.assertEquals(t2, root.list[2])
// remove a trigger
root.list.remove(t1)
Assert.assertEquals(2, root.size())
Assert.assertEquals(t0, root.list[0])
Assert.assertEquals(t2, root.list[1])
}
@Test
fun testChangeConnector() {
// initialize scenario
val root = TriggerConnector(injector, TriggerConnector.Type.AND)
val t = arrayOfNulls<Trigger>(4)
for (i in t.indices) {
t[i] = TriggerDummy(injector)
root.list.add(t[i]!!)
}
Assert.assertEquals(4, root.size())
}
}

View file

@ -1,112 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.triggers;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import info.AAPSMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.utils.SP;
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, L.class, SP.class})
public class TriggerConnectorTest {
@Test
public void testTriggerList() {
TriggerConnector t = new TriggerConnector();
TriggerConnector t2 = new TriggerConnector();
TriggerConnector t3 = new TriggerConnector();
Assert.assertTrue(t.size() == 0);
t.add(t2);
Assert.assertTrue(t.size() == 1);
Assert.assertEquals(t2, t.get(0));
t.add(t3);
Assert.assertTrue(t.size() == 2);
Assert.assertEquals(t2, t.get(0));
Assert.assertEquals(t3, t.get(1));
Assert.assertTrue(t.remove(t2));
Assert.assertTrue(t.size() == 1);
Assert.assertEquals(t3, t.get(0));
Assert.assertTrue(t.shouldRun());
}
@Test
public void testListTriggerOR() {
TriggerConnector t = new TriggerConnector(TriggerConnector.Type.OR);
t.add(new DummyTrigger(false));
t.add(new DummyTrigger(false));
Assert.assertFalse(t.shouldRun());
t.add(new DummyTrigger(true));
t.add(new DummyTrigger(false));
Assert.assertTrue(t.shouldRun());
}
@Test
public void testListTriggerXOR() {
TriggerConnector t = new TriggerConnector(TriggerConnector.Type.XOR);
t.add(new DummyTrigger(false));
t.add(new DummyTrigger(false));
Assert.assertFalse(t.shouldRun());
t.add(new DummyTrigger(true));
t.add(new DummyTrigger(false));
Assert.assertTrue(t.shouldRun());
t.add(new DummyTrigger(true));
t.add(new DummyTrigger(false));
Assert.assertFalse(t.shouldRun());
}
@Test
public void testListTriggerAND() {
TriggerConnector t = new TriggerConnector(TriggerConnector.Type.AND);
t.add(new DummyTrigger(true));
t.add(new DummyTrigger(true));
Assert.assertTrue(t.shouldRun());
t.add(new DummyTrigger(true));
t.add(new DummyTrigger(false));
Assert.assertFalse(t.shouldRun());
}
static public final String empty = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[]},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\"}";
static public final String oneItem = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\"]},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\"}";
@Test
public void toJSONTest() {
TriggerConnector t = new TriggerConnector();
Assert.assertEquals(empty, t.toJSON());
t.add(new TriggerConnector());
Assert.assertEquals(oneItem, t.toJSON());
}
@Test
public void fromJSONTest() throws JSONException {
TriggerConnector t = new TriggerConnector();
t.add(new TriggerConnector());
TriggerConnector t2 = (TriggerConnector) Trigger.instantiate(new JSONObject(t.toJSON()));
Assert.assertEquals(1, t2.size());
Assert.assertTrue(t2.get(0) instanceof TriggerConnector);
}
@Before
public void prepareMock() {
AAPSMocker.mockMainApp();
AAPSMocker.mockSP();
AAPSMocker.mockL();
}
}

View file

@ -0,0 +1,83 @@
package info.nightscout.androidaps.plugins.general.automation.triggers
import org.json.JSONException
import org.json.JSONObject
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
class TriggerConnectorTest : TriggerTestBase() {
@Test fun testTriggerList() {
val t = TriggerConnector(injector)
val t2 = TriggerConnector(injector)
val t3 = TriggerConnector(injector)
Assert.assertTrue(t.size() == 0)
t.list.add(t2)
Assert.assertTrue(t.size() == 1)
Assert.assertEquals(t2, t.list.get(0))
t.list.add(t3)
Assert.assertTrue(t.size() == 2)
Assert.assertEquals(t2, t.list.get(0))
Assert.assertEquals(t3, t.list.get(1))
Assert.assertTrue(t.list.remove(t2))
Assert.assertTrue(t.size() == 1)
Assert.assertEquals(t3, t.list.get(0))
Assert.assertTrue(t.shouldRun())
}
@Test fun testListTriggerOR() {
val t = TriggerConnector(injector, TriggerConnector.Type.OR)
t.list.add(TriggerDummy(injector))
t.list.add(TriggerDummy(injector))
Assert.assertFalse(t.shouldRun())
t.list.add(TriggerDummy(injector, true))
t.list.add(TriggerDummy(injector))
Assert.assertTrue(t.shouldRun())
}
@Test fun testListTriggerXOR() {
val t = TriggerConnector(injector, TriggerConnector.Type.XOR)
t.list.add(TriggerDummy(injector))
t.list.add(TriggerDummy(injector))
Assert.assertFalse(t.shouldRun())
t.list.add(TriggerDummy(injector, true))
t.list.add(TriggerDummy(injector))
Assert.assertTrue(t.shouldRun())
t.list.add(TriggerDummy(injector, true))
t.list.add(TriggerDummy(injector))
Assert.assertFalse(t.shouldRun())
}
@Test fun testListTriggerAND() {
val t = TriggerConnector(injector, TriggerConnector.Type.AND)
t.list.add(TriggerDummy(injector, true))
t.list.add(TriggerDummy(injector, true))
Assert.assertTrue(t.shouldRun())
t.list.add(TriggerDummy(injector, true))
t.list.add(TriggerDummy(injector))
Assert.assertFalse(t.shouldRun())
}
@Test fun toJSONTest() {
val t = TriggerConnector(injector)
Assert.assertEquals(empty, t.toJSON())
t.list.add(TriggerConnector(injector))
Assert.assertEquals(oneItem, t.toJSON())
}
@Test @Throws(JSONException::class) fun fromJSONTest() {
val t = TriggerConnector(injector)
t.list.add(TriggerConnector(injector))
val t2 = TriggerDummy(injector).instantiate(JSONObject(t.toJSON())) as TriggerConnector
Assert.assertEquals(1, t2.size().toLong())
Assert.assertTrue(t2.list[0] is TriggerConnector)
}
companion object {
const val empty = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[]},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\"}"
const val oneItem = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\"]},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\"}"
}
}

View file

@ -0,0 +1,45 @@
package info.nightscout.androidaps.plugins.general.automation.triggers
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.TestBase
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.mockito.Mock
import org.powermock.core.classloader.annotations.PrepareForTest
@PrepareForTest(LastLocationDataContainer::class)
open class TriggerTestBase : TestBase() {
@Mock lateinit var aapsLogger: AAPSLogger
@Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var sp: SP
@Mock lateinit var locationDataContainer: LastLocationDataContainer
@Mock lateinit var treatmentsPlugin: TreatmentsPlugin
@Mock lateinit var activePlugin: ActivePluginProvider
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
var injector: HasAndroidInjector = HasAndroidInjector {
AndroidInjector {
if (it is Trigger) {
it.aapsLogger = aapsLogger
it.rxBus = RxBusWrapper()
it.resourceHelper = resourceHelper
it.profileFunction = profileFunction
it.locationDataContainer = locationDataContainer
it.treatmentsPlugin = treatmentsPlugin
it.activePlugin = activePlugin
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
}
}
}
}