Files
JIMRI/java/test/jmri/jmrit/logixng/util/parser/ExpressionNodeMethodTest.java
2026-06-17 14:00:51 +02:00

291 lines
12 KiB
Java

package jmri.jmrit.logixng.util.parser;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.awt.geom.Point2D;
import java.io.*;
import java.util.*;
import jmri.JmriException;
import jmri.jmrit.display.layoutEditor.*;
import jmri.jmrit.logixng.SymbolTable;
import jmri.jmrit.logixng.implementation.DefaultConditionalNG;
import jmri.jmrit.logixng.implementation.DefaultSymbolTable;
import jmri.util.JUnitUtil;
import jmri.util.junit.annotations.DisabledIfHeadless;
import org.junit.jupiter.api.*;
/**
* Test ExpressionNodeMethod.
* This method is also used to create the ExpressionNodeMethodPrimTest.java source file.
*
* @author Daniel Bergqvist 2024
*/
public class ExpressionNodeMethodTest {
public void testCall(Object object, String method, Object expectedResult, Object[] params)
throws FunctionNotExistsException, JmriException {
Map<String, Variable> variables = new HashMap<>();
List<ExpressionNode> parameterList = new ArrayList<>();
SymbolTable symbolTable = new DefaultSymbolTable(new DefaultConditionalNG("IQC1", null));
for (Object p : params) {
parameterList.add(new MyExpressionNode(p));
}
ExpressionNodeMethod t = new ExpressionNodeMethod(method, variables, parameterList);
Object result = t.calculate(object, symbolTable);
Assertions.assertEquals(expectedResult, result);
}
@Test
public void testExpressionNodeMethod() throws JmriException {
testCall("Hello", "substring", "ell", new Object[]{1,4});
}
@Test
public void testMapEntry() throws JmriException {
// HashMap.entrySet() returns a set of classes that are private.
// We cannot use reflection to call methods on a class that's private.
Map<String, String> map = new HashMap<>();
map.put("Hello", "World");
var entry = map.entrySet().iterator().next();
testCall(entry, "getKey", "Hello", new Object[]{});
testCall(entry, "getValue", "World", new Object[]{});
testCall(entry, "toString", "Hello=World", new Object[]{});
}
@Test
@DisabledIfHeadless
public void testMethodWithBooleanParameter() throws JmriException {
var editor = new jmri.jmrit.display.layoutEditor.LayoutEditor("My layout");
// code retained for any future debug
// jmri.util.ThreadingUtil.runOnGUI( () -> editor.setVisible(true));
// jmri.jmrit.display.EditorFrameOperator efo = new jmri.jmrit.display.EditorFrameOperator("My layout");
// Assertions.assertNotNull(efo);
PositionablePoint p1 = new PositionablePoint("A", PositionablePoint.PointType.ANCHOR, editor);
PositionablePointView p1v = new PositionablePointView(p1, new Point2D.Double(210.0, 220.0), editor);
editor.addLayoutTrack(p1, p1v);
PositionablePoint p2 = new PositionablePoint("B", PositionablePoint.PointType.ANCHOR, editor);
PositionablePointView p2v = new PositionablePointView(p2, new Point2D.Double(220.0, 233.0), editor);
editor.addLayoutTrack(p2, p2v);
var trackSegment = new TrackSegment("Id", p1, HitPointType.POS_POINT, p2, HitPointType.POS_POINT, false, editor);
var trackSegmentView = new TrackSegmentView(trackSegment, editor);
editor.addLayoutTrack(trackSegment, trackSegmentView);
var segments = editor.getTrackSegmentViews();
var segment = segments.get(0);
segment.setHidden(false);
Assertions.assertFalse(segment.isHidden());
testCall(segment, "setHidden", null, new Object[]{true});
Assertions.assertTrue(segment.isHidden());
JUnitUtil.dispose(editor);
}
/**
* This method creates the ExpressionNodeMethodPrimTest.java source file.
* Comment out the line "@Disabled" and run this test to create the file.
* @throws IOException if an I/O exception occurs.
*/
@Disabled("Comment out this line to regenerate tests")
@Test
@SuppressFBWarnings( value="VA_FORMAT_STRING_USES_NEWLINE", justification="JMRI uses LF line endings, not platform specific")
public void testCreateTestMethods() throws IOException {
String filename = "java/test/jmri/jmrit/logixng/util/parser/ExpressionNodeMethodPrimTest.java";
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filename)))) {
writer.format(
"package jmri.jmrit.logixng.util.parser;\n" +
"\n" +
"/**\n" +
" * Important!!!\n" +
" * This file is created by ExpressionNodeMethodTest.testCreateTestMethods()\n" +
" * Comment out @Disabled if you want to regenerate this file.\n" +
" */\n" +
"\n" +
"import static org.junit.jupiter.api.Assertions.assertEquals;\n\n" +
"import java.util.*;\n" +
"\n" +
"import jmri.JmriException;\n" +
"import jmri.jmrit.logixng.SymbolTable;\n" +
"import jmri.jmrit.logixng.implementation.DefaultConditionalNG;\n" +
"import jmri.jmrit.logixng.implementation.DefaultSymbolTable;\n" +
"import jmri.util.JUnitUtil;\n" +
"\n" +
"import org.junit.jupiter.api.AfterEach;\n" +
"import org.junit.jupiter.api.BeforeEach;\n" +
"import org.junit.jupiter.api.Test;\n" +
"\n" +
"/**\n" +
" * Test ParsedExpression\n" +
" *\n" +
" * @author Daniel Bergqvist 2024\n" +
" */\n" +
"public class ExpressionNodeMethodPrimTest {\n" +
"\n" +
" private static final TestClass tc = new TestClass();\n" +
"\n" +
" public void testCall(Object object, String method, Object expectedResult, Object[] params)\n" +
" throws FunctionNotExistsException, JmriException {\n" +
"\n" +
" Map<String, Variable> variables = new HashMap<>();\n" +
" List<ExpressionNode> parameterList = new ArrayList<>();\n" +
" SymbolTable symbolTable = new DefaultSymbolTable(new DefaultConditionalNG(\"IQC1\", null));\n" +
"\n" +
" for (Object p : params) {\n" +
" parameterList.add(new MyExpressionNode(p));\n" +
" }\n" +
"\n" +
" ExpressionNodeMethod t = new ExpressionNodeMethod(method, variables, parameterList);\n" +
" Object result = t.calculate(object, symbolTable);\n" +
"\n" +
" assertEquals(expectedResult, result);\n" +
" }\n" +
"\n" +
"");
String[] classes = new String[]{"Byte", "Short", "Integer", "Long", "Float", "Double"};
String[] types = new String[]{"byte", "short", "int", "long", "float", "double"};
for (int i=0; i < classes.length; i++) {
if (i > 0) {
writer.format(
" }\n" +
"\n");
}
writer.format(
" @Test\n" +
" public void test%s() throws FunctionNotExistsException, JmriException {\n" +
"", classes[i]);
for (int j=0; j < classes.length; j++) {
for (int k=0; k < classes.length; k++) {
for (int l=0; l < classes.length; l++) {
String result = "8L";
if ("Float".equals(classes[i])) result = "8D";
if ("Double".equals(classes[i])) result = "8D";
if ("Float".equals(classes[j])) result = "8D";
if ("Double".equals(classes[j])) result = "8D";
if (("float".equals(types[k]) || "double".equals(types[k]))
&& (!"Float".equals(classes[i]) && !"Double".equals(classes[i]))) continue;
if (("float".equals(types[l]) || "double".equals(types[l]))
&& (!"Float".equals(classes[j]) && !"Double".equals(classes[j]))) continue;
String object1 = ( "int".equals(types[k]) ? "" : "(" + types[k] + ")");
String object2 = ( "int".equals(types[l]) ? "" : "(" + types[l] + ")");
writer.format(" testCall(tc, \"test%s%s\", null, new Object[]{%s2,%s4});\n", classes[i], classes[j], object1, object2);
writer.format(" testCall(tc, \"test%s%sResult\", %s, new Object[]{%s2,%s4});\n", classes[i], classes[j], result, object1, object2);
}
}
}
}
writer.format(" }\n");
writer.format(
"\n" +
" @BeforeEach\n" +
" public void setUp() {\n" +
" JUnitUtil.setUp();\n" +
" }\n" +
"\n" +
" @AfterEach\n" +
" public void tearDown() {\n" +
" JUnitUtil.tearDown();\n" +
" }\n" +
"\n" +
"\n" +
" private static class MyExpressionNode implements ExpressionNode {\n" +
"\n" +
" private final Object _value;\n" +
"\n" +
" private MyExpressionNode(Object value) {\n" +
" _value = value;\n" +
" }\n" +
"\n" +
" @Override\n" +
" public Object calculate(SymbolTable symbolTable) throws JmriException {\n" +
" return _value;\n" +
" }\n" +
"\n" +
" @Override\n" +
" public String getDefinitionString() {\n" +
" throw new UnsupportedOperationException(\"Not supported yet.\");\n" +
" }\n" +
"\n" +
" }\n" +
"\n" +
"\n" +
" public static class TestClass {\n" +
"\n");
for (int i=0; i < classes.length; i++) {
for (int j=0; j < classes.length; j++) {
String result = "long";
if ("Float".equals(classes[i])) result = "double";
if ("Double".equals(classes[i])) result = "double";
if ("Float".equals(classes[j])) result = "double";
if ("Double".equals(classes[j])) result = "double";
String longReturn = ( "long".equals(result) ? "1L * " : "" );
writer.format(" public void test%s%s(%s a, %s b) { }\n", classes[i], classes[j], types[i], types[j]);
writer.format(" public %s test%s%sResult(%s a, %s b) { return %sa*b; }\n", result, classes[i], classes[j], types[i], types[j], longReturn);
}
}
writer.format(" }\n");
writer.format("\n");
writer.format("}\n");
}
}
@BeforeEach
public void setUp() {
JUnitUtil.setUp();
}
@AfterEach
public void tearDown() {
JUnitUtil.deregisterBlockManagerShutdownTask();
JUnitUtil.tearDown();
}
private static class MyExpressionNode implements ExpressionNode {
private final Object _value;
private MyExpressionNode(Object value) {
_value = value;
}
@Override
public Object calculate(SymbolTable symbolTable) throws JmriException {
return _value;
}
@Override
public String getDefinitionString() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}