Files
JIMRI/java/test/jmri/jmrit/logixng/actions/ForEachTest.java
T
2026-06-17 14:00:51 +02:00

319 lines
13 KiB
Java

package jmri.jmrit.logixng.actions;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.*;
import jmri.*;
import jmri.jmrit.logixng.*;
import jmri.jmrit.logixng.implementation.DefaultConditionalNGScaffold;
import jmri.jmrit.logixng.util.parser.ParserException;
import jmri.util.JUnitUtil;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test ForEach
*
* @author Daniel Bergqvist 2024
*/
public class ForEachTest extends AbstractDigitalActionTestBase {
private Memory _memory;
private Memory _memoryResult;
private LogixNG _logixNG;
private ConditionalNG _conditionalNG;
private ForEach _forEach;
private MaleSocket _maleSocket;
private DigitalFormula _formula;
@Override
public ConditionalNG getConditionalNG() {
return _conditionalNG;
}
@Override
public LogixNG getLogixNG() {
return _logixNG;
}
@Override
public MaleSocket getConnectableChild() {
DigitalMany action = new DigitalMany("IQDA999", null);
MaleSocket maleSocket =
InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
return maleSocket;
}
@Override
public String getExpectedPrintedTree() {
return String.format(
"For each value, set variable \"item\" and execute action A. Values from memory IM1 ::: Use default%n" +
" ::: Local variable \"item\", init to None \"null\"%n" +
" ! A%n" +
" Digital Formula: writeMemory(\"IMResult\", readMemory(\"IMResult\") + item + \", \") ::: Use default%n" +
" ?* E1%n" +
" Socket not connected%n");
}
@Override
public String getExpectedPrintedTreeFromRoot() {
return String.format(
"LogixNG: A new logix for test%n" +
" ConditionalNG: A conditionalNG%n" +
" ! A%n" +
" For each value, set variable \"item\" and execute action A. Values from memory IM1 ::: Use default%n" +
" ::: Local variable \"item\", init to None \"null\"%n" +
" ! A%n" +
" Digital Formula: writeMemory(\"IMResult\", readMemory(\"IMResult\") + item + \", \") ::: Use default%n" +
" ?* E1%n" +
" Socket not connected%n");
}
@Override
public NamedBean createNewBean(String systemName) {
return new TableForEach(systemName, null);
}
@Override
public boolean addNewSocket() {
return false;
}
@Test
public void testCtor() {
TableForEach t = new TableForEach("IQDA321", null);
assertNotNull( t, "exists");
t = new TableForEach("IQDA321", null);
assertNotNull( t, "exists");
}
@Test
public void testGetChild() {
assertEquals( 1, _forEach.getChildCount(), "getChildCount() returns 1");
assertNotNull( _forEach.getChild(0), "getChild(0) returns a non null value");
IllegalArgumentException ex = assertThrows( IllegalArgumentException.class, () ->
_forEach.getChild(1), "Exception is thrown");
assertEquals( "index has invalid value: 1", ex.getMessage(),
"Error message is correct");
}
@Test
public void testCategory() {
assertSame( LogixNG_Category.FLOW_CONTROL, _base.getCategory(), "Category matches");
}
@Test
public void testDescription() {
ForEach a1 = new ForEach("IQDA321", null);
assertEquals( "For each", a1.getShortDescription(), "strings are equal");
ForEach a2 = new ForEach("IQDA321", null);
assertEquals( "For each value, set variable \"\" and execute action A. Values from Sensors",
a2.getLongDescription(), "strings are equal");
}
@Test
public void testExecute()
throws IOException, SocketAlreadyConnectedException, ParserException {
_memory.setValue(new ArrayList<String>());
_memoryResult.setValue("");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item + \", \")");
_logixNG.execute();
assertEquals("", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from memory IM1",
_forEach.getLongDescription());
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
_memory.setValue(list);
_memoryResult.setValue("");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item + \", \")");
_logixNG.execute();
assertEquals("A, B, C, ", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from memory IM1",
_forEach.getLongDescription());
Map<String, Integer> map = new HashMap<>();
map.put("A", 10);
map.put("B", 20);
map.put("C", -3);
_memory.setValue(map);
_memoryResult.setValue("");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item.getKey() + \":\" + str(item.getValue()) + \", \")");
_logixNG.execute();
assertEquals("A:10, B:20, C:-3, ", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from memory IM1",
_forEach.getLongDescription());
map = new HashMap<>();
map.put("A", 8);
map.put("B", -55);
map.put("C", 32);
_memory.setValue(map);
_memoryResult.setValue("");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + \"toString:>\" + item.toString() + \"<\" + \", \")");
_logixNG.execute();
assertEquals("toString:>A=8<, toString:>B=-55<, toString:>C=32<, ", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from memory IM1",
_forEach.getLongDescription());
map = new HashMap<>();
map.put("A", 8);
map.put("B", -55);
map.put("C", 32);
_memory.setValue(map);
_memoryResult.setValue("");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + \"getClass().getName():>\" + item.getClass().getName() + \"<\" + \", \")");
_logixNG.execute();
assertEquals("getClass().getName():>java.util.HashMap$Node<, getClass().getName():>java.util.HashMap$Node<, getClass().getName():>java.util.HashMap$Node<, ",
_memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from memory IM1",
_forEach.getLongDescription());
_memory.setValue(new String[]{"A", "B", "C"});
_memoryResult.setValue("");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item + \", \")");
_logixNG.execute();
assertEquals("A, B, C, ", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from memory IM1",
_forEach.getLongDescription());
_memoryResult.setValue("");
_forEach.setUseCommonSource(true);
_forEach.setCommonManager(CommonManager.Sensors);
InstanceManager.getDefault(SensorManager.class).provideSensor("ISSomething");
InstanceManager.getDefault(SensorManager.class).provideSensor("ISSomethingElse");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item.getSystemName() + \", \")");
_logixNG.execute();
assertEquals("ISCLOCKRUNNING, ISSomething, ISSomethingElse, ", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from Sensors",
_forEach.getLongDescription());
_memoryResult.setValue("");
_forEach.setUseCommonSource(true);
_forEach.setCommonManager(CommonManager.Turnouts);
InstanceManager.getDefault(TurnoutManager.class).provideTurnout("ITSomething");
InstanceManager.getDefault(TurnoutManager.class).provideTurnout("ITSomethingElse");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item.getSystemName() + \", \")");
_logixNG.execute();
assertEquals("ITSomething, ITSomethingElse, ", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from Turnouts",
_forEach.getLongDescription());
_memoryResult.setValue("");
_forEach.setUseCommonSource(true);
_forEach.setCommonManager(CommonManager.Lights);
InstanceManager.getDefault(LightManager.class).provideLight("ILSomething");
InstanceManager.getDefault(LightManager.class).provideLight("ILSomethingElse");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item.getSystemName() + \", \")");
_logixNG.execute();
assertEquals("ILSomething, ILSomethingElse, ", _memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from Lights",
_forEach.getLongDescription());
_memoryResult.setValue("");
_forEach.setUseCommonSource(true);
_forEach.setCommonManager(CommonManager.Memories);
InstanceManager.getDefault(MemoryManager.class).provideMemory("IMSomething");
InstanceManager.getDefault(MemoryManager.class).provideMemory("IMSomethingElse");
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item.getSystemName() + \", \")");
_logixNG.execute();
assertEquals("IM1, IMCURRENTTIME, IMRATEFACTOR, IMResult, IMSomething, IMSomethingElse, ",
_memoryResult.getValue());
assertEquals("For each value, set variable \"item\" and execute action A. Values from Memories",
_forEach.getLongDescription());
}
@Test
@Override
public void testIsActive() {
_logixNG.setEnabled(true);
super.testIsActive();
}
@Test
@Override
public void testMaleSocketIsActive() {
_logixNG.setEnabled(true);
super.testMaleSocketIsActive();
}
@BeforeEach
public void setUp() throws SocketAlreadyConnectedException, ParserException {
JUnitUtil.setUp();
JUnitUtil.resetInstanceManager();
JUnitUtil.resetProfileManager();
JUnitUtil.initConfigureManager();
JUnitUtil.initInternalSensorManager();
JUnitUtil.initInternalTurnoutManager();
JUnitUtil.initLogixNGManager();
_category = LogixNG_Category.OTHER;
_isExternal = false;
_memory = InstanceManager.getDefault(MemoryManager.class).provideMemory("IM1"); // NOI18N
_memory.setValue(new ArrayList<String>());
_memoryResult = InstanceManager.getDefault(MemoryManager.class).provideMemory("IMResult"); // NOI18N
_memoryResult.setValue("");
_logixNG = InstanceManager.getDefault(LogixNG_Manager.class).createLogixNG("A new logix for test"); // NOI18N
_conditionalNG = new DefaultConditionalNGScaffold("IQC1", "A conditionalNG"); // NOI18N;
InstanceManager.getDefault(ConditionalNG_Manager.class).register(_conditionalNG);
_conditionalNG.setEnabled(true);
_conditionalNG.setRunDelayed(false);
_logixNG.addConditionalNG(_conditionalNG);
_forEach = new ForEach("IQDA321", null);
_forEach.setUserSpecifiedSource(ForEach.UserSpecifiedSource.Memory);
_forEach.setUseCommonSource(false);
_forEach.getSelectMemoryNamedBean().setNamedBean(_memory);
_forEach.setLocalVariableName("item");
_maleSocket =
InstanceManager.getDefault(DigitalActionManager.class).registerAction(_forEach);
_maleSocket.addLocalVariable("item", SymbolTable.InitialValueType.None, null);
_conditionalNG.getChild(0).connect(_maleSocket);
_base = _forEach;
_baseMaleSocket = _maleSocket;
_formula = new DigitalFormula(
InstanceManager.getDefault(DigitalActionManager.class).getAutoSystemName(), null);
_formula.setFormula("writeMemory(\"IMResult\", readMemory(\"IMResult\") + item + \", \")");
_forEach.getChild(0).connect(InstanceManager.getDefault(DigitalActionManager.class)
.registerAction(_formula));
assertTrue( _logixNG.setParentForAllChildren(new ArrayList<>()));
_logixNG.activate();
_logixNG.setEnabled(false);
}
@AfterEach
public void tearDown() {
_logixNG.setEnabled(false);
jmri.jmrit.logixng.util.LogixNG_Thread.stopAllLogixNGThreads();
JUnitUtil.deregisterBlockManagerShutdownTask();
JUnitUtil.tearDown();
_category = null;
_memory = null;
_memoryResult = null;
_logixNG = null;
_conditionalNG = null;
_forEach = null;
_base = null;
_baseMaleSocket = null;
_maleSocket = null;
}
}