diff --git a/src/main/java/de/neemann/digital/cli/CommandLineTester.java b/src/main/java/de/neemann/digital/cli/CommandLineTester.java index c27d356d0..03c8fba42 100644 --- a/src/main/java/de/neemann/digital/cli/CommandLineTester.java +++ b/src/main/java/de/neemann/digital/cli/CommandLineTester.java @@ -74,20 +74,20 @@ public class CommandLineTester { try { ErrorDetector errorDetector = new ErrorDetector(); - TestExecutor te = new TestExecutor(t, circuitLoader.getCircuit(), circuitLoader.getLibrary()) + TestExecutor.Result tr = new TestExecutor(t, circuitLoader.getCircuit(), circuitLoader.getLibrary()) .setAllowMissingInputs(allowMissingInputs) .addObserver(errorDetector) - .create(); + .execute(); - if (te.allPassed()) { + if (tr.allPassed()) { out.println(label + ": passed"); testsPassed++; } else { String message = label + ": failed"; - if (te.isErrorOccurred()) + if (tr.isErrorOccurred()) message += " due to an error"; else - message += " (" + te.failedPercent() + "%)"; + message += " (" + tr.failedPercent() + "%)"; out.println(message); errorCount++; } diff --git a/src/main/java/de/neemann/digital/draw/elements/Circuit.java b/src/main/java/de/neemann/digital/draw/elements/Circuit.java index d8fe498c5..49a14e739 100644 --- a/src/main/java/de/neemann/digital/draw/elements/Circuit.java +++ b/src/main/java/de/neemann/digital/draw/elements/Circuit.java @@ -365,17 +365,6 @@ public class Circuit implements Copyable { private final boolean hasGenericCode; private final VisualElement visualElement; - /** - * Used in some test cases. - * Don't use this constructor in production code! - * - * @param testCaseDescription the test case description - */ - public TestCase(TestCaseDescription testCaseDescription) { - this(new VisualElement(TestCaseElement.DESCRIPTION.getName()) - .setAttribute(Keys.TESTDATA, testCaseDescription)); - } - private TestCase(VisualElement visualElement) { this.visualElement = visualElement; ElementAttributes attr = visualElement.getElementAttributes(); @@ -406,7 +395,7 @@ public class Circuit implements Copyable { } /** - * @return the visual element which contains the test case, maybe null + * @return the visual element which contains the test case */ public VisualElement getVisualElement() { return visualElement; @@ -425,7 +414,6 @@ public class Circuit implements Copyable { TestCase testCase = (TestCase) o; return label.equals(testCase.label); - } @Override diff --git a/src/main/java/de/neemann/digital/gui/components/testing/ValueTableDialog.java b/src/main/java/de/neemann/digital/gui/components/testing/ValueTableDialog.java index 9c24ab431..1b13308db 100644 --- a/src/main/java/de/neemann/digital/gui/components/testing/ValueTableDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/testing/ValueTableDialog.java @@ -125,13 +125,13 @@ public class ValueTableDialog extends JDialog { for (Circuit.TestCase ts : tsl) { ErrorDetector errorDetector = new ErrorDetector(); try { - TestExecutor testExecutor = new TestExecutor(ts, circuit, library) + TestExecutor.Result testResult = new TestExecutor(ts, circuit, library) .addObserver(errorDetector) - .create(); + .execute(); String tabName; Icon tabIcon; - if (testExecutor.allPassed()) { + if (testResult.allPassed()) { tabName = Lang.get("msg_test_N_Passed", ts.getLabel()); tabIcon = ICON_PASSED; } else { @@ -139,13 +139,13 @@ public class ValueTableDialog extends JDialog { tabIcon = ICON_FAILED; errorTabIndex = i; } - if (testExecutor.toManyResults()) + if (testResult.toManyResults()) tabName += " " + Lang.get("msg_test_missingLines"); - tp.addTab(tabName, tabIcon, new JScrollPane(createTable(testExecutor.getResult()))); - if (testExecutor.toManyResults()) + tp.addTab(tabName, tabIcon, new JScrollPane(createTable(testResult.getValueTable()))); + if (testResult.toManyResults()) tp.setToolTipTextAt(i, new LineBreaker().toHTML().breakLines(Lang.get("msg_test_missingLines_tt"))); - resultTableData.add(testExecutor.getResult()); + resultTableData.add(testResult.getValueTable()); i++; errorDetector.check(); } catch (Exception e) { diff --git a/src/main/java/de/neemann/digital/testing/FolderTestRunner.java b/src/main/java/de/neemann/digital/testing/FolderTestRunner.java index 05dc27cc8..198a9ed8e 100644 --- a/src/main/java/de/neemann/digital/testing/FolderTestRunner.java +++ b/src/main/java/de/neemann/digital/testing/FolderTestRunner.java @@ -199,9 +199,9 @@ public class FolderTestRunner { int rowCount = 0; for (Circuit.TestCase tc : testCases) { try { - TestExecutor te = new TestExecutor(tc, circuit, library).create(); - if (te.allPassed()) { - rowCount += te.getResult().getRows(); + TestExecutor.Result tr = new TestExecutor(tc, circuit, library).execute(); + if (tr.allPassed()) { + rowCount += tr.getValueTable().getRows(); } else { if (sb.length() > 0) sb.append("; "); diff --git a/src/main/java/de/neemann/digital/testing/TestExecutor.java b/src/main/java/de/neemann/digital/testing/TestExecutor.java index 645a83def..fb1005fc6 100644 --- a/src/main/java/de/neemann/digital/testing/TestExecutor.java +++ b/src/main/java/de/neemann/digital/testing/TestExecutor.java @@ -57,7 +57,7 @@ public class TestExecutor { * @throws NodeException NodeException */ public TestExecutor(Circuit.TestCase testCase, Circuit circuit, ElementLibrary library) throws TestingDataException, NodeException, ElementNotFoundException, PinException { - this(testCase, createModel(testCase, circuit, library)); + this(testCase.getTestCaseDescription(), createModel(testCase, circuit, library)); } static private Model createModel(Circuit.TestCase testCase, Circuit circuit, ElementLibrary library) throws NodeException, ElementNotFoundException, PinException { @@ -71,30 +71,30 @@ public class TestExecutor { } /** - * Use for tests only! Do'nt use this constructor with a model you have created from a circuit. - * If a circuit is available use the other constructor. + * Use for tests only! Don't use this constructor with a model you have created from a circuit. + * If a circuit is available use the constructor above. * * @param testCase the test case * @param model the model * @throws TestingDataException TestingDataException */ - public TestExecutor(Circuit.TestCase testCase, Model model) throws TestingDataException { - names = testCase.getTestCaseDescription().getNames(); + public TestExecutor(TestCaseDescription testCase, Model model) throws TestingDataException { + names = testCase.getNames(); this.model = model; results = new ValueTable(names); visibleRows = 0; - lines = testCase.getTestCaseDescription().getLines(); + lines = testCase.getLines(); } /** - * Creates the result by comparing the testing vector with the given model- + * Creates the result by comparing the testing vector with the given model * - * @return this for chained calls + * @return the result of the test execution * @throws TestingDataException DataException * @throws NodeException NodeException * @throws ParserException ParserException */ - public TestExecutor create() throws TestingDataException, NodeException, ParserException { + public TestExecutor.Result execute() throws TestingDataException, NodeException, ParserException { try { HashSet usedSignals = new HashSet<>(); inputs = new ArrayList<>(); @@ -153,7 +153,7 @@ public class TestExecutor { lines.emitLines(new LineListenerResolveDontCare(values -> checkRow(model, values), inputs), new Context().setModel(model)); - return this; + return new Result(); } finally { model.close(); } @@ -243,42 +243,6 @@ public class TestExecutor { toManyResults = true; } - /** - * @return true if all tests have passed - */ - public boolean allPassed() { - return !errorOccurred && failedCount == 0 && passedCount > 0; - } - - /** - * @return true if the test failed due to an error - */ - public boolean isErrorOccurred() { - return errorOccurred; - } - - /** - * @return the percentage of failed test rows - */ - public int failedPercent() { - if (passedCount == 0) - return 100; - int p = 100 * failedCount / passedCount; - if (p == 0 && failedCount > 0) - p = 1; - return p; - } - - /** - * Indicates if there are to many entries in the table to show. - * If there are to many entries, the test results is still correct. - * - * @return true if there are missing items in the results list. - */ - public boolean toManyResults() { - return toManyResults; - } - private int getIndexOf(String name) { if (name == null || name.length() == 0) return -1; @@ -291,13 +255,6 @@ public class TestExecutor { return -1; } - /** - * @return return the result - */ - public ValueTable getResult() { - return results; - } - /** * Allow missing inputs * @@ -323,11 +280,11 @@ public class TestExecutor { /** * A test signal */ - public static class TestSignal { + public final static class TestSignal { private final int index; private final ObservableValue value; - TestSignal(int index, ObservableValue value) { + private TestSignal(int index, ObservableValue value) { this.index = index; this.value = value; } @@ -340,4 +297,55 @@ public class TestExecutor { } } + /** + * The result of the test execution + */ + public final class Result { + + private Result() { + } + + /** + * @return true if all tests have passed + */ + public boolean allPassed() { + return !errorOccurred && failedCount == 0 && passedCount > 0; + } + + /** + * @return true if the test failed due to an error + */ + public boolean isErrorOccurred() { + return errorOccurred; + } + + /** + * @return the percentage of failed test rows + */ + public int failedPercent() { + if (passedCount == 0) + return 100; + int p = 100 * failedCount / passedCount; + if (p == 0 && failedCount > 0) + p = 1; + return p; + } + + /** + * Indicates if there are to many entries in the table to show. + * If there are to many entries, the test results is still correct. + * + * @return true if there are missing items in the results list. + */ + public boolean toManyResults() { + return toManyResults; + } + + /** + * @return the value table containing the detailed result + */ + public ValueTable getValueTable() { + return results; + } + } } diff --git a/src/test/java/de/neemann/digital/draw/library/JarComponentManagerTest.java b/src/test/java/de/neemann/digital/draw/library/JarComponentManagerTest.java index 3613bf4e9..880511f0c 100644 --- a/src/test/java/de/neemann/digital/draw/library/JarComponentManagerTest.java +++ b/src/test/java/de/neemann/digital/draw/library/JarComponentManagerTest.java @@ -34,6 +34,6 @@ public class JarComponentManagerTest extends TestCase { }; for (Circuit.TestCase tc : br.getCircuit().getTestCases()) - assertTrue(new TestExecutor(tc, br.getCircuit(), br.getLibrary()).create().allPassed()); + assertTrue(new TestExecutor(tc, br.getCircuit(), br.getLibrary()).execute().allPassed()); } } diff --git a/src/test/java/de/neemann/digital/integration/TestExamples.java b/src/test/java/de/neemann/digital/integration/TestExamples.java index 6e8348774..a5888dfcd 100644 --- a/src/test/java/de/neemann/digital/integration/TestExamples.java +++ b/src/test/java/de/neemann/digital/integration/TestExamples.java @@ -6,7 +6,6 @@ package de.neemann.digital.integration; import de.neemann.digital.core.ErrorDetector; -import de.neemann.digital.core.Model; import de.neemann.digital.core.NodeException; import de.neemann.digital.core.element.Keys; import de.neemann.digital.draw.elements.Circuit; @@ -83,9 +82,9 @@ public class TestExamples extends TestCase { String label = tc.getLabel(); ErrorDetector ed = new ErrorDetector(); - TestExecutor tr = new TestExecutor(tc, br.getCircuit(), br.getLibrary()) + TestExecutor.Result tr = new TestExecutor(tc, br.getCircuit(), br.getLibrary()) .addObserver(ed) - .create(); + .execute(); if (label.contains("Failing")) assertFalse(dig.getName() + ":" + label, tr.allPassed()); diff --git a/src/test/java/de/neemann/digital/testing/TestResultTest.java b/src/test/java/de/neemann/digital/testing/TestResultTest.java index 1e86ee6c1..47009e9a3 100644 --- a/src/test/java/de/neemann/digital/testing/TestResultTest.java +++ b/src/test/java/de/neemann/digital/testing/TestResultTest.java @@ -47,8 +47,8 @@ public class TestResultTest extends TestCase { + "0 1 1\n" + "1 0 1\n" + "1 1 0\n"); - TestExecutor tr = new TestExecutor(new Circuit.TestCase(data), model).create(); - assertEquals(4, tr.getResult().getRows()); + TestExecutor.Result tr = new TestExecutor(data, model).execute(); + assertEquals(4, tr.getValueTable().getRows()); assertTrue(tr.allPassed()); } @@ -60,14 +60,14 @@ public class TestResultTest extends TestCase { + "0 1 1\n" + "1 0 1\n" + "1 1 0\n"); - TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create(); - ValueTable tr = te.getResult(); - assertEquals(4, tr.getRows()); - assertFalse(te.allPassed()); - assertEquals(true, ((MatchedValue) tr.getValue(0, 2)).isPassed()); - assertEquals(true, ((MatchedValue) tr.getValue(1, 2)).isPassed()); - assertEquals(true, ((MatchedValue) tr.getValue(2, 2)).isPassed()); - assertEquals(false, ((MatchedValue) tr.getValue(3, 2)).isPassed()); + TestExecutor.Result tr = new TestExecutor(data, model).execute(); + ValueTable valueTable = tr.getValueTable(); + assertEquals(4, valueTable.getRows()); + assertFalse(tr.allPassed()); + assertEquals(true, ((MatchedValue) valueTable.getValue(0, 2)).isPassed()); + assertEquals(true, ((MatchedValue) valueTable.getValue(1, 2)).isPassed()); + assertEquals(true, ((MatchedValue) valueTable.getValue(2, 2)).isPassed()); + assertEquals(false, ((MatchedValue) valueTable.getValue(3, 2)).isPassed()); } public void testResultDontCare() throws Exception { @@ -78,10 +78,10 @@ public class TestResultTest extends TestCase { + "0 1 1\n" + "1 0 1\n" + "1 1 x\n"); - TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create(); - ValueTable tr = te.getResult(); - assertEquals(4, tr.getRows()); - assertTrue(te.allPassed()); + TestExecutor.Result tr = new TestExecutor(data, model).execute(); + ValueTable valueTable = tr.getValueTable(); + assertEquals(4, valueTable.getRows()); + assertTrue(tr.allPassed()); } public void testResultDontCare2() throws Exception { @@ -92,10 +92,10 @@ public class TestResultTest extends TestCase { + "0 1 1\n" + "1 0 1\n" + "1 1 1\n"); - TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create(); - ValueTable tr = te.getResult(); - assertEquals(4, tr.getRows()); - assertTrue(te.allPassed()); + TestExecutor.Result tr = new TestExecutor(data, model).execute(); + ValueTable valueTable = tr.getValueTable(); + assertEquals(4, valueTable.getRows()); + assertTrue(tr.allPassed()); } public void testResultDontCareInput() throws Exception { @@ -104,10 +104,10 @@ public class TestResultTest extends TestCase { "A B Y\n" + "x 0 0\n" + "x 1 1\n"); - TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create(); - ValueTable tr = te.getResult(); - assertEquals(4, tr.getRows()); - assertTrue(te.allPassed()); + TestExecutor.Result tr = new TestExecutor(data, model).execute(); + ValueTable valueTable = tr.getValueTable(); + assertEquals(4, valueTable.getRows()); + assertTrue(tr.allPassed()); } public void testResultDontCareInput2() throws Exception { @@ -116,10 +116,10 @@ public class TestResultTest extends TestCase { "A B C Y\n" + "x x 0 0\n" + "x x 1 1\n"); - TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create(); - ValueTable tr = te.getResult(); - assertEquals(8, tr.getRows()); - assertTrue(te.allPassed()); + TestExecutor.Result tr = new TestExecutor(data, model).execute(); + ValueTable valueTable = tr.getValueTable(); + assertEquals(8, valueTable.getRows()); + assertTrue(tr.allPassed()); } }