refactored test result to new data structure

This commit is contained in:
hneemann 2017-07-03 10:50:05 +02:00
parent 33288750b1
commit 218b6e6895
21 changed files with 193 additions and 100 deletions

View File

@ -1,4 +1,4 @@
package de.neemann.digital.testing;
package de.neemann.digital.data;
import de.neemann.digital.core.ObservableValue;
@ -10,7 +10,7 @@ import de.neemann.digital.core.ObservableValue;
public class Value {
/**
* Types of values
* Types of value
*/
public enum Type {
/**
@ -31,6 +31,25 @@ public class Value {
CLOCK
}
/**
* state of value
*/
public enum State {
/**
* a normals value
*/
NORMAL,
/**
* value is a passed test
*/
PASS,
/**
* value is a failed test
*/
FAIL
}
private final long value;
private final Type type;
@ -135,6 +154,13 @@ public class Value {
return type;
}
/**
* @return the state of this value
*/
public State getState() {
return State.NORMAL;
}
/**
* @return true if value is a high Z value
*/

View File

@ -0,0 +1,67 @@
package de.neemann.digital.data;
import java.util.ArrayList;
/**
* Stores values in a table
* Created by hneemann on 03.07.17.
*/
public class ValueTable {
private final ArrayList<String> names;
private final ArrayList<Value[]> values;
/**
* Creates a new table.
*
* @param names the cignal names
*/
public ValueTable(ArrayList<String> names) {
this.names = names;
values = new ArrayList<>();
}
/**
* @return number of rows
*/
public int getRows() {
return values.size();
}
/**
* add values without copying them
*
* @param row a row to insert, values are not copied!
*/
public void add(Value[] row) {
values.add(row);
}
/**
* provides the values
*
* @param rowIndex the wow
* @param columnIndex the column
* @return the value stored at the given position
*/
public Value getValue(int rowIndex, int columnIndex) {
return values.get(rowIndex)[columnIndex];
}
/**
* the number of signals
* @return the column count
*/
public int getColumns() {
return names.size();
}
/**
* Returns the column names
* @param col the column
* @return the name
*/
public String getColumnName(int col) {
return names.get(col);
}
}

View File

@ -1,8 +1,6 @@
package de.neemann.digital.gui.components.testing;
package de.neemann.digital.data;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.MatchedValue;
import de.neemann.digital.testing.TestResult;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
@ -12,27 +10,27 @@ import javax.swing.table.TableModel;
* <p>
* Created by hneemann on 24.08.16.
*/
public class TestResultModel implements TableModel {
public class ValueTableModel implements TableModel {
private final TestResult testResult;
private final ValueTable values;
/**
* Creates a new table model
*
* @param testResult the testresult to wrap
* @param values the values to wrap
*/
public TestResultModel(TestResult testResult) {
this.testResult = testResult;
public ValueTableModel(ValueTable values) {
this.values = values;
}
@Override
public int getRowCount() {
return testResult.getRows();
return values.getRows();
}
@Override
public int getColumnCount() {
return testResult.getSignalCount() + 1;
return values.getColumns() + 1;
}
@Override
@ -40,7 +38,7 @@ public class TestResultModel implements TableModel {
if (columnIndex == 0)
return Lang.get("number");
else
return testResult.getSignalName(columnIndex - 1);
return values.getColumnName(columnIndex - 1);
}
@Override
@ -48,7 +46,7 @@ public class TestResultModel implements TableModel {
if (columnIndex == 0)
return Integer.class;
else
return MatchedValue.class;
return Value.class;
}
@Override
@ -61,7 +59,7 @@ public class TestResultModel implements TableModel {
if (columnIndex == 0)
return rowIndex;
else
return testResult.getResultValue(rowIndex, columnIndex - 1);
return values.getValue(rowIndex, columnIndex - 1);
}

View File

@ -0,0 +1,5 @@
/**
* Classes to store signal data
* Created by hneemann on 03.07.17.
*/
package de.neemann.digital.data;

View File

@ -2,6 +2,8 @@ package de.neemann.digital.gui.components.testing;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.data.ValueTableModel;
import de.neemann.digital.data.Value;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementLibrary;
@ -54,13 +56,13 @@ public class TestResultDialog extends JDialog {
for (TestSet ts : tsl) {
Model model = new ModelCreator(circuit, library).createModel(false);
TestResult tr = new TestResult(ts.data).create(model);
TestExecuter testExecuter = new TestExecuter(ts.data).create(model);
if (tr.getException() != null)
SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorWhileExecutingTests_N0", ts.name)).addCause(tr.getException()).setComponent(this));
if (testExecuter.getException() != null)
SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorWhileExecutingTests_N0", ts.name)).addCause(testExecuter.getException()).setComponent(this));
JTable table = new JTable(new TestResultModel(tr));
table.setDefaultRenderer(MatchedValue.class, new MatchedValueRenderer());
JTable table = new JTable(new ValueTableModel(testExecuter.getResult()));
table.setDefaultRenderer(Value.class, new ValueRenderer());
table.setDefaultRenderer(Integer.class, new NumberRenderer());
final Font font = table.getFont();
table.getColumnModel().getColumn(0).setMaxWidth(font.getSize()*4);
@ -68,7 +70,7 @@ public class TestResultDialog extends JDialog {
String tabName;
Icon tabIcon;
if (tr.allPassed()) {
if (testExecuter.allPassed()) {
tabName = Lang.get("msg_test_N_Passed", ts.name);
tabIcon = ICON_PASSED;
} else {
@ -76,11 +78,11 @@ public class TestResultDialog extends JDialog {
tabIcon = ICON_FAILED;
errorTabIndex = i;
}
if (tr.toManyResults())
if (testExecuter.toManyResults())
tabName += " " + Lang.get("msg_test_missingLines");
tp.addTab(tabName, tabIcon, new JScrollPane(table));
if (tr.toManyResults())
if (testExecuter.toManyResults())
tp.setToolTipTextAt(i, new LineBreaker().toHTML().breakLines(Lang.get("msg_test_missingLines_tt")));
i++;
}
@ -134,7 +136,7 @@ public class TestResultDialog extends JDialog {
}
}
private static class MatchedValueRenderer extends DefaultTableCellRenderer {
private static class ValueRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
@ -144,13 +146,17 @@ public class TestResultDialog extends JDialog {
comp.setText(v.toString());
comp.setHorizontalAlignment(JLabel.CENTER);
if (v instanceof MatchedValue) {
if (((MatchedValue) v).isPassed())
comp.setBackground(PASSED_COLOR);
else
comp.setBackground(FAILED_COLOR);
} else
switch (((Value) value).getState()) {
case NORMAL:
comp.setBackground(Color.WHITE);
break;
case FAIL:
comp.setBackground(FAILED_COLOR);
break;
case PASS:
comp.setBackground(PASSED_COLOR);
break;
}
}
return comp;
}

View File

@ -1,5 +1,6 @@
package de.neemann.digital.testing;
import de.neemann.digital.data.Value;
import de.neemann.digital.testing.parser.LineListener;
import java.util.ArrayList;
@ -11,7 +12,7 @@ import java.util.ArrayList;
public class LineListenerResolveDontCare implements LineListener {
private final LineListener parent;
private final ArrayList<TestResult.TestSignal> inputs;
private final ArrayList<TestExecuter.TestSignal> inputs;
/**
* Create a new instance
@ -19,7 +20,7 @@ public class LineListenerResolveDontCare implements LineListener {
* @param parent the parent listener
* @param inputs the input test signals
*/
public LineListenerResolveDontCare(LineListener parent, ArrayList<TestResult.TestSignal> inputs) {
public LineListenerResolveDontCare(LineListener parent, ArrayList<TestExecuter.TestSignal> inputs) {
this.parent = parent;
this.inputs = inputs;
}
@ -27,7 +28,7 @@ public class LineListenerResolveDontCare implements LineListener {
@Override
public void add(Value[] rowWithDontCare) {
ArrayList<Integer> dcIndex = null;
for (TestResult.TestSignal in : inputs) {
for (TestExecuter.TestSignal in : inputs) {
if (rowWithDontCare[in.getIndex()].getType() == Value.Type.DONTCARE) {
if (dcIndex == null)
dcIndex = new ArrayList<>();

View File

@ -1,6 +1,7 @@
package de.neemann.digital.testing;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.data.Value;
import de.neemann.digital.lang.Lang;
/**
@ -18,7 +19,7 @@ public class MatchedValue extends Value {
* @param expected the expected value
* @param found the found value
*/
public MatchedValue(Value expected, ObservableValue found) {
MatchedValue(Value expected, ObservableValue found) {
super(found);
this.expected = expected;
}
@ -26,7 +27,7 @@ public class MatchedValue extends Value {
/**
* @return true if test is passed
*/
public boolean isPassed() {
boolean isPassed() {
return isEqualTo(expected);
}
@ -37,4 +38,12 @@ public class MatchedValue extends Value {
else
return Lang.get("msg_testExp_N0_found_N1", expected, super.toString());
}
@Override
public State getState() {
if (isPassed())
return State.PASS;
else
return State.FAIL;
}
}

View File

@ -5,6 +5,8 @@ import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.core.Signal;
import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.data.Value;
import de.neemann.digital.data.ValueTable;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.parser.Context;
import de.neemann.digital.testing.parser.LineEmitter;
@ -19,13 +21,13 @@ import java.util.HashSet;
*
* @author hneemann
*/
public class TestResult {
public class TestExecuter {
private static final int MAX_RESULTS = 1 << 10;
private static final int ERR_RESULTS = MAX_RESULTS * 2;
private final ArrayList<String> names;
private final LineEmitter lines;
private final ArrayList<Value[]> results;
private final ValueTable results;
private boolean allPassed;
private Exception exception;
private boolean toManyResults = false;
@ -38,10 +40,10 @@ public class TestResult {
* @param testData the testing data
* @throws TestingDataException DataException
*/
public TestResult(TestData testData) throws TestingDataException {
public TestExecuter(TestData testData) throws TestingDataException {
names = testData.getNames();
results = new ValueTable(names);
lines = testData.getLines();
results = new ArrayList<>();
}
/**
@ -52,7 +54,7 @@ public class TestResult {
* @throws TestingDataException DataException
* @throws NodeException NodeException
*/
public TestResult create(Model model) throws TestingDataException, NodeException {
public TestExecuter create(Model model) throws TestingDataException, NodeException {
allPassed = true;
HashSet<String> usedSignals = new HashSet<>();
@ -162,7 +164,7 @@ public class TestResult {
}
}
if (results.size() < (ok ? MAX_RESULTS : ERR_RESULTS))
if (results.getRows() < (ok ? MAX_RESULTS : ERR_RESULTS))
results.add(res);
else
toManyResults = true;
@ -199,38 +201,10 @@ public class TestResult {
}
/**
* @return the number of rows
* @return return the result
*/
public int getRows() {
return results.size();
}
/**
* @return the number of signals
*/
public int getSignalCount() {
return names.size();
}
/**
* returns a signal name
*
* @param index the index of the requested signals name
* @return the signals name
*/
public String getSignalName(int index) {
return names.get(index);
}
/**
* Returns the typed value
*
* @param rowIndex rowIndex
* @param columnIndex columnIndex
* @return the value
*/
public Value getResultValue(int rowIndex, int columnIndex) {
return results.get(rowIndex)[columnIndex];
public ValueTable getResult() {
return results;
}
/**

View File

@ -1,6 +1,7 @@
package de.neemann.digital.testing;
import de.neemann.digital.core.element.PinDescription;
import de.neemann.digital.data.Value;
import de.neemann.digital.testing.parser.Context;
import de.neemann.digital.testing.parser.Parser;
import de.neemann.digital.testing.parser.ParserException;

View File

@ -1,7 +1,7 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import java.util.ArrayList;

View File

@ -1,6 +1,6 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
/**
* Listener for truth table lines

View File

@ -1,7 +1,7 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.lang.Lang;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import java.io.BufferedReader;
import java.io.IOException;

View File

@ -1,6 +1,6 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import java.util.ArrayList;

View File

@ -1,6 +1,6 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import java.util.ArrayList;

View File

@ -3,7 +3,7 @@ package de.neemann.digital.core.pld;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementNotFoundException;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import junit.framework.TestCase;
import java.io.IOException;

View File

@ -5,7 +5,7 @@ import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.testing.TestCaseElement;
import de.neemann.digital.testing.TestData;
import de.neemann.digital.testing.TestResult;
import de.neemann.digital.testing.TestExecuter;
import junit.framework.TestCase;
import java.io.File;
@ -69,7 +69,7 @@ public class TestExamples extends TestCase {
TestData td = el.getElementAttributes().get(TestCaseElement.TESTDATA);
Model model = new ModelCreator(br.getCircuit(), br.getLibrary()).createModel(false);
TestResult tr = new TestResult(td).create(model);
TestExecuter tr = new TestExecuter(td).create(model);
if (label.contains("Failing"))
assertFalse(dig.getName() + ":" + label, tr.allPassed());

View File

@ -7,6 +7,7 @@ import de.neemann.digital.builder.BuilderException;
import de.neemann.digital.builder.circuit.CircuitBuilder;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.data.ValueTable;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementLibrary;
@ -42,8 +43,8 @@ public class TestResultTest extends TestCase {
+ "0 1 1\n"
+ "1 0 1\n"
+ "1 1 0\n");
TestResult tr = new TestResult(data).create(model);
assertEquals(4,tr.getRows());
TestExecuter tr = new TestExecuter(data).create(model);
assertEquals(4,tr.getResult().getRows());
assertTrue(tr.allPassed());
}
@ -55,13 +56,14 @@ public class TestResultTest extends TestCase {
+ "0 1 1\n"
+ "1 0 1\n"
+ "1 1 0\n");
TestResult tr = new TestResult(data).create(model);
TestExecuter te = new TestExecuter(data).create(model);
ValueTable tr = te.getResult();
assertEquals(4,tr.getRows());
assertFalse(tr.allPassed());
assertEquals(true, ((MatchedValue) tr.getResultValue(0, 2)).isPassed());
assertEquals(true, ((MatchedValue) tr.getResultValue(1, 2)).isPassed());
assertEquals(true, ((MatchedValue) tr.getResultValue(2, 2)).isPassed());
assertEquals(false, ((MatchedValue) tr.getResultValue(3, 2)).isPassed());
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());
}
public void testResultDontCare() throws Exception {
@ -72,9 +74,10 @@ public class TestResultTest extends TestCase {
+ "0 1 1\n"
+ "1 0 1\n"
+ "1 1 x\n");
TestResult tr = new TestResult(data).create(model);
TestExecuter te = new TestExecuter(data).create(model);
ValueTable tr = te.getResult();
assertEquals(4,tr.getRows());
assertTrue(tr.allPassed());
assertTrue(te.allPassed());
}
public void testResultDontCare2() throws Exception {
@ -85,9 +88,10 @@ public class TestResultTest extends TestCase {
+ "0 1 1\n"
+ "1 0 1\n"
+ "1 1 1\n");
TestResult tr = new TestResult(data).create(model);
TestExecuter te = new TestExecuter(data).create(model);
ValueTable tr = te.getResult();
assertEquals(4,tr.getRows());
assertTrue(tr.allPassed());
assertTrue(te.allPassed());
}
public void testResultDontCareInput() throws Exception {
@ -96,9 +100,10 @@ public class TestResultTest extends TestCase {
"A B Y\n"
+ "x 0 0\n"
+ "x 1 1\n");
TestResult tr = new TestResult(data).create(model);
TestExecuter te = new TestExecuter(data).create(model);
ValueTable tr = te.getResult();
assertEquals(4,tr.getRows());
assertTrue(tr.allPassed());
assertTrue(te.allPassed());
}
public void testResultDontCareInput2() throws Exception {
@ -107,9 +112,10 @@ public class TestResultTest extends TestCase {
"A B C Y\n"
+ "x x 0 0\n"
+ "x x 1 1\n");
TestResult tr = new TestResult(data).create(model);
TestExecuter te = new TestExecuter(data).create(model);
ValueTable tr = te.getResult();
assertEquals(8,tr.getRows());
assertTrue(tr.allPassed());
assertTrue(te.allPassed());
}
}

View File

@ -1,6 +1,6 @@
package de.neemann.digital.testing;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import junit.framework.TestCase;
/**

View File

@ -1,6 +1,6 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import java.util.ArrayList;

View File

@ -1,6 +1,6 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import junit.framework.TestCase;
import java.io.IOException;

View File

@ -1,7 +1,7 @@
package de.neemann.digital.testing.parser;
import de.neemann.digital.testing.TestingDataException;
import de.neemann.digital.testing.Value;
import de.neemann.digital.data.Value;
import junit.framework.TestCase;
import java.io.IOException;