mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-16 00:15:01 -04:00
minor refactoring of the test executor
This commit is contained in:
parent
1de3a42570
commit
b04b469b71
@ -74,20 +74,20 @@ public class CommandLineTester {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ErrorDetector errorDetector = new ErrorDetector();
|
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)
|
.setAllowMissingInputs(allowMissingInputs)
|
||||||
.addObserver(errorDetector)
|
.addObserver(errorDetector)
|
||||||
.create();
|
.execute();
|
||||||
|
|
||||||
if (te.allPassed()) {
|
if (tr.allPassed()) {
|
||||||
out.println(label + ": passed");
|
out.println(label + ": passed");
|
||||||
testsPassed++;
|
testsPassed++;
|
||||||
} else {
|
} else {
|
||||||
String message = label + ": failed";
|
String message = label + ": failed";
|
||||||
if (te.isErrorOccurred())
|
if (tr.isErrorOccurred())
|
||||||
message += " due to an error";
|
message += " due to an error";
|
||||||
else
|
else
|
||||||
message += " (" + te.failedPercent() + "%)";
|
message += " (" + tr.failedPercent() + "%)";
|
||||||
out.println(message);
|
out.println(message);
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
|
@ -365,17 +365,6 @@ public class Circuit implements Copyable<Circuit> {
|
|||||||
private final boolean hasGenericCode;
|
private final boolean hasGenericCode;
|
||||||
private final VisualElement visualElement;
|
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) {
|
private TestCase(VisualElement visualElement) {
|
||||||
this.visualElement = visualElement;
|
this.visualElement = visualElement;
|
||||||
ElementAttributes attr = visualElement.getElementAttributes();
|
ElementAttributes attr = visualElement.getElementAttributes();
|
||||||
@ -406,7 +395,7 @@ public class Circuit implements Copyable<Circuit> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the visual element which contains the test case, maybe null
|
* @return the visual element which contains the test case
|
||||||
*/
|
*/
|
||||||
public VisualElement getVisualElement() {
|
public VisualElement getVisualElement() {
|
||||||
return visualElement;
|
return visualElement;
|
||||||
@ -425,7 +414,6 @@ public class Circuit implements Copyable<Circuit> {
|
|||||||
TestCase testCase = (TestCase) o;
|
TestCase testCase = (TestCase) o;
|
||||||
|
|
||||||
return label.equals(testCase.label);
|
return label.equals(testCase.label);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -125,13 +125,13 @@ public class ValueTableDialog extends JDialog {
|
|||||||
for (Circuit.TestCase ts : tsl) {
|
for (Circuit.TestCase ts : tsl) {
|
||||||
ErrorDetector errorDetector = new ErrorDetector();
|
ErrorDetector errorDetector = new ErrorDetector();
|
||||||
try {
|
try {
|
||||||
TestExecutor testExecutor = new TestExecutor(ts, circuit, library)
|
TestExecutor.Result testResult = new TestExecutor(ts, circuit, library)
|
||||||
.addObserver(errorDetector)
|
.addObserver(errorDetector)
|
||||||
.create();
|
.execute();
|
||||||
|
|
||||||
String tabName;
|
String tabName;
|
||||||
Icon tabIcon;
|
Icon tabIcon;
|
||||||
if (testExecutor.allPassed()) {
|
if (testResult.allPassed()) {
|
||||||
tabName = Lang.get("msg_test_N_Passed", ts.getLabel());
|
tabName = Lang.get("msg_test_N_Passed", ts.getLabel());
|
||||||
tabIcon = ICON_PASSED;
|
tabIcon = ICON_PASSED;
|
||||||
} else {
|
} else {
|
||||||
@ -139,13 +139,13 @@ public class ValueTableDialog extends JDialog {
|
|||||||
tabIcon = ICON_FAILED;
|
tabIcon = ICON_FAILED;
|
||||||
errorTabIndex = i;
|
errorTabIndex = i;
|
||||||
}
|
}
|
||||||
if (testExecutor.toManyResults())
|
if (testResult.toManyResults())
|
||||||
tabName += " " + Lang.get("msg_test_missingLines");
|
tabName += " " + Lang.get("msg_test_missingLines");
|
||||||
|
|
||||||
tp.addTab(tabName, tabIcon, new JScrollPane(createTable(testExecutor.getResult())));
|
tp.addTab(tabName, tabIcon, new JScrollPane(createTable(testResult.getValueTable())));
|
||||||
if (testExecutor.toManyResults())
|
if (testResult.toManyResults())
|
||||||
tp.setToolTipTextAt(i, new LineBreaker().toHTML().breakLines(Lang.get("msg_test_missingLines_tt")));
|
tp.setToolTipTextAt(i, new LineBreaker().toHTML().breakLines(Lang.get("msg_test_missingLines_tt")));
|
||||||
resultTableData.add(testExecutor.getResult());
|
resultTableData.add(testResult.getValueTable());
|
||||||
i++;
|
i++;
|
||||||
errorDetector.check();
|
errorDetector.check();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -199,9 +199,9 @@ public class FolderTestRunner {
|
|||||||
int rowCount = 0;
|
int rowCount = 0;
|
||||||
for (Circuit.TestCase tc : testCases) {
|
for (Circuit.TestCase tc : testCases) {
|
||||||
try {
|
try {
|
||||||
TestExecutor te = new TestExecutor(tc, circuit, library).create();
|
TestExecutor.Result tr = new TestExecutor(tc, circuit, library).execute();
|
||||||
if (te.allPassed()) {
|
if (tr.allPassed()) {
|
||||||
rowCount += te.getResult().getRows();
|
rowCount += tr.getValueTable().getRows();
|
||||||
} else {
|
} else {
|
||||||
if (sb.length() > 0)
|
if (sb.length() > 0)
|
||||||
sb.append("; ");
|
sb.append("; ");
|
||||||
|
@ -57,7 +57,7 @@ public class TestExecutor {
|
|||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
*/
|
*/
|
||||||
public TestExecutor(Circuit.TestCase testCase, Circuit circuit, ElementLibrary library) throws TestingDataException, NodeException, ElementNotFoundException, PinException {
|
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 {
|
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.
|
* 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 other constructor.
|
* If a circuit is available use the constructor above.
|
||||||
*
|
*
|
||||||
* @param testCase the test case
|
* @param testCase the test case
|
||||||
* @param model the model
|
* @param model the model
|
||||||
* @throws TestingDataException TestingDataException
|
* @throws TestingDataException TestingDataException
|
||||||
*/
|
*/
|
||||||
public TestExecutor(Circuit.TestCase testCase, Model model) throws TestingDataException {
|
public TestExecutor(TestCaseDescription testCase, Model model) throws TestingDataException {
|
||||||
names = testCase.getTestCaseDescription().getNames();
|
names = testCase.getNames();
|
||||||
this.model = model;
|
this.model = model;
|
||||||
results = new ValueTable(names);
|
results = new ValueTable(names);
|
||||||
visibleRows = 0;
|
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 TestingDataException DataException
|
||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
* @throws ParserException ParserException
|
* @throws ParserException ParserException
|
||||||
*/
|
*/
|
||||||
public TestExecutor create() throws TestingDataException, NodeException, ParserException {
|
public TestExecutor.Result execute() throws TestingDataException, NodeException, ParserException {
|
||||||
try {
|
try {
|
||||||
HashSet<String> usedSignals = new HashSet<>();
|
HashSet<String> usedSignals = new HashSet<>();
|
||||||
inputs = new ArrayList<>();
|
inputs = new ArrayList<>();
|
||||||
@ -153,7 +153,7 @@ public class TestExecutor {
|
|||||||
|
|
||||||
lines.emitLines(new LineListenerResolveDontCare(values -> checkRow(model, values), inputs), new Context().setModel(model));
|
lines.emitLines(new LineListenerResolveDontCare(values -> checkRow(model, values), inputs), new Context().setModel(model));
|
||||||
|
|
||||||
return this;
|
return new Result();
|
||||||
} finally {
|
} finally {
|
||||||
model.close();
|
model.close();
|
||||||
}
|
}
|
||||||
@ -243,6 +243,68 @@ public class TestExecutor {
|
|||||||
toManyResults = true;
|
toManyResults = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getIndexOf(String name) {
|
||||||
|
if (name == null || name.length() == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < names.size(); i++) {
|
||||||
|
String n = names.get(i);
|
||||||
|
if (n.equals(name))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow missing inputs
|
||||||
|
*
|
||||||
|
* @param allowMissingInputs if true, missing inputs are allowed
|
||||||
|
* @return this for chained calls
|
||||||
|
*/
|
||||||
|
public TestExecutor setAllowMissingInputs(boolean allowMissingInputs) {
|
||||||
|
this.allowMissingInputs = allowMissingInputs;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a observer to the model of this test executor
|
||||||
|
*
|
||||||
|
* @param observer the observer to add
|
||||||
|
* @return this for chained calls
|
||||||
|
*/
|
||||||
|
public TestExecutor addObserver(ModelStateObserverTyped observer) {
|
||||||
|
model.addObserver(observer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test signal
|
||||||
|
*/
|
||||||
|
public final static class TestSignal {
|
||||||
|
private final int index;
|
||||||
|
private final ObservableValue value;
|
||||||
|
|
||||||
|
private TestSignal(int index, ObservableValue value) {
|
||||||
|
this.index = index;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the index of this value
|
||||||
|
*/
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result of the test execution
|
||||||
|
*/
|
||||||
|
public final class Result {
|
||||||
|
|
||||||
|
private Result() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if all tests have passed
|
* @return true if all tests have passed
|
||||||
*/
|
*/
|
||||||
@ -279,65 +341,11 @@ public class TestExecutor {
|
|||||||
return toManyResults;
|
return toManyResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getIndexOf(String name) {
|
|
||||||
if (name == null || name.length() == 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < names.size(); i++) {
|
|
||||||
String n = names.get(i);
|
|
||||||
if (n.equals(name))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return return the result
|
* @return the value table containing the detailed result
|
||||||
*/
|
*/
|
||||||
public ValueTable getResult() {
|
public ValueTable getValueTable() {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow missing inputs
|
|
||||||
*
|
|
||||||
* @param allowMissingInputs if true, missing inputs are allowed
|
|
||||||
* @return this for chained calls
|
|
||||||
*/
|
|
||||||
public TestExecutor setAllowMissingInputs(boolean allowMissingInputs) {
|
|
||||||
this.allowMissingInputs = allowMissingInputs;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a observer to the model of this test executor
|
|
||||||
*
|
|
||||||
* @param observer the observer to add
|
|
||||||
* @return this for chained calls
|
|
||||||
*/
|
|
||||||
public TestExecutor addObserver(ModelStateObserverTyped observer) {
|
|
||||||
model.addObserver(observer);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A test signal
|
|
||||||
*/
|
|
||||||
public static class TestSignal {
|
|
||||||
private final int index;
|
|
||||||
private final ObservableValue value;
|
|
||||||
|
|
||||||
TestSignal(int index, ObservableValue value) {
|
|
||||||
this.index = index;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the index of this value
|
|
||||||
*/
|
|
||||||
public int getIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -34,6 +34,6 @@ public class JarComponentManagerTest extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (Circuit.TestCase tc : br.getCircuit().getTestCases())
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
package de.neemann.digital.integration;
|
package de.neemann.digital.integration;
|
||||||
|
|
||||||
import de.neemann.digital.core.ErrorDetector;
|
import de.neemann.digital.core.ErrorDetector;
|
||||||
import de.neemann.digital.core.Model;
|
|
||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.NodeException;
|
||||||
import de.neemann.digital.core.element.Keys;
|
import de.neemann.digital.core.element.Keys;
|
||||||
import de.neemann.digital.draw.elements.Circuit;
|
import de.neemann.digital.draw.elements.Circuit;
|
||||||
@ -83,9 +82,9 @@ public class TestExamples extends TestCase {
|
|||||||
String label = tc.getLabel();
|
String label = tc.getLabel();
|
||||||
|
|
||||||
ErrorDetector ed = new ErrorDetector();
|
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)
|
.addObserver(ed)
|
||||||
.create();
|
.execute();
|
||||||
|
|
||||||
if (label.contains("Failing"))
|
if (label.contains("Failing"))
|
||||||
assertFalse(dig.getName() + ":" + label, tr.allPassed());
|
assertFalse(dig.getName() + ":" + label, tr.allPassed());
|
||||||
|
@ -47,8 +47,8 @@ public class TestResultTest extends TestCase {
|
|||||||
+ "0 1 1\n"
|
+ "0 1 1\n"
|
||||||
+ "1 0 1\n"
|
+ "1 0 1\n"
|
||||||
+ "1 1 0\n");
|
+ "1 1 0\n");
|
||||||
TestExecutor tr = new TestExecutor(new Circuit.TestCase(data), model).create();
|
TestExecutor.Result tr = new TestExecutor(data, model).execute();
|
||||||
assertEquals(4, tr.getResult().getRows());
|
assertEquals(4, tr.getValueTable().getRows());
|
||||||
assertTrue(tr.allPassed());
|
assertTrue(tr.allPassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,14 +60,14 @@ public class TestResultTest extends TestCase {
|
|||||||
+ "0 1 1\n"
|
+ "0 1 1\n"
|
||||||
+ "1 0 1\n"
|
+ "1 0 1\n"
|
||||||
+ "1 1 0\n");
|
+ "1 1 0\n");
|
||||||
TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create();
|
TestExecutor.Result tr = new TestExecutor(data, model).execute();
|
||||||
ValueTable tr = te.getResult();
|
ValueTable valueTable = tr.getValueTable();
|
||||||
assertEquals(4, tr.getRows());
|
assertEquals(4, valueTable.getRows());
|
||||||
assertFalse(te.allPassed());
|
assertFalse(tr.allPassed());
|
||||||
assertEquals(true, ((MatchedValue) tr.getValue(0, 2)).isPassed());
|
assertEquals(true, ((MatchedValue) valueTable.getValue(0, 2)).isPassed());
|
||||||
assertEquals(true, ((MatchedValue) tr.getValue(1, 2)).isPassed());
|
assertEquals(true, ((MatchedValue) valueTable.getValue(1, 2)).isPassed());
|
||||||
assertEquals(true, ((MatchedValue) tr.getValue(2, 2)).isPassed());
|
assertEquals(true, ((MatchedValue) valueTable.getValue(2, 2)).isPassed());
|
||||||
assertEquals(false, ((MatchedValue) tr.getValue(3, 2)).isPassed());
|
assertEquals(false, ((MatchedValue) valueTable.getValue(3, 2)).isPassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testResultDontCare() throws Exception {
|
public void testResultDontCare() throws Exception {
|
||||||
@ -78,10 +78,10 @@ public class TestResultTest extends TestCase {
|
|||||||
+ "0 1 1\n"
|
+ "0 1 1\n"
|
||||||
+ "1 0 1\n"
|
+ "1 0 1\n"
|
||||||
+ "1 1 x\n");
|
+ "1 1 x\n");
|
||||||
TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create();
|
TestExecutor.Result tr = new TestExecutor(data, model).execute();
|
||||||
ValueTable tr = te.getResult();
|
ValueTable valueTable = tr.getValueTable();
|
||||||
assertEquals(4, tr.getRows());
|
assertEquals(4, valueTable.getRows());
|
||||||
assertTrue(te.allPassed());
|
assertTrue(tr.allPassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testResultDontCare2() throws Exception {
|
public void testResultDontCare2() throws Exception {
|
||||||
@ -92,10 +92,10 @@ public class TestResultTest extends TestCase {
|
|||||||
+ "0 1 1\n"
|
+ "0 1 1\n"
|
||||||
+ "1 0 1\n"
|
+ "1 0 1\n"
|
||||||
+ "1 1 1\n");
|
+ "1 1 1\n");
|
||||||
TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create();
|
TestExecutor.Result tr = new TestExecutor(data, model).execute();
|
||||||
ValueTable tr = te.getResult();
|
ValueTable valueTable = tr.getValueTable();
|
||||||
assertEquals(4, tr.getRows());
|
assertEquals(4, valueTable.getRows());
|
||||||
assertTrue(te.allPassed());
|
assertTrue(tr.allPassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testResultDontCareInput() throws Exception {
|
public void testResultDontCareInput() throws Exception {
|
||||||
@ -104,10 +104,10 @@ public class TestResultTest extends TestCase {
|
|||||||
"A B Y\n"
|
"A B Y\n"
|
||||||
+ "x 0 0\n"
|
+ "x 0 0\n"
|
||||||
+ "x 1 1\n");
|
+ "x 1 1\n");
|
||||||
TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create();
|
TestExecutor.Result tr = new TestExecutor(data, model).execute();
|
||||||
ValueTable tr = te.getResult();
|
ValueTable valueTable = tr.getValueTable();
|
||||||
assertEquals(4, tr.getRows());
|
assertEquals(4, valueTable.getRows());
|
||||||
assertTrue(te.allPassed());
|
assertTrue(tr.allPassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testResultDontCareInput2() throws Exception {
|
public void testResultDontCareInput2() throws Exception {
|
||||||
@ -116,10 +116,10 @@ public class TestResultTest extends TestCase {
|
|||||||
"A B C Y\n"
|
"A B C Y\n"
|
||||||
+ "x x 0 0\n"
|
+ "x x 0 0\n"
|
||||||
+ "x x 1 1\n");
|
+ "x x 1 1\n");
|
||||||
TestExecutor te = new TestExecutor(new Circuit.TestCase(data), model).create();
|
TestExecutor.Result tr = new TestExecutor(data, model).execute();
|
||||||
ValueTable tr = te.getResult();
|
ValueTable valueTable = tr.getValueTable();
|
||||||
assertEquals(8, tr.getRows());
|
assertEquals(8, valueTable.getRows());
|
||||||
assertTrue(te.allPassed());
|
assertTrue(tr.allPassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user