mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-28 15:32:40 -04:00
refactoring of testing: separated test execution from test result/test case visualization.
This commit is contained in:
parent
a3fc6845d4
commit
89a726dc25
@ -20,7 +20,7 @@ import de.neemann.digital.draw.shapes.Drawable;
|
|||||||
import de.neemann.digital.draw.shapes.InputShape;
|
import de.neemann.digital.draw.shapes.InputShape;
|
||||||
import de.neemann.digital.draw.shapes.ShapeFactory;
|
import de.neemann.digital.draw.shapes.ShapeFactory;
|
||||||
import de.neemann.digital.gui.components.AttributeDialog;
|
import de.neemann.digital.gui.components.AttributeDialog;
|
||||||
import de.neemann.digital.gui.components.test.TestData;
|
import de.neemann.digital.testing.TestData;
|
||||||
import de.neemann.digital.gui.sync.NoSync;
|
import de.neemann.digital.gui.sync.NoSync;
|
||||||
import de.neemann.digital.gui.sync.Sync;
|
import de.neemann.digital.gui.sync.Sync;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
@ -15,7 +15,7 @@ import de.neemann.digital.gui.components.data.DummyElement;
|
|||||||
import de.neemann.digital.gui.components.graphics.GraphicCard;
|
import de.neemann.digital.gui.components.graphics.GraphicCard;
|
||||||
import de.neemann.digital.gui.components.terminal.Keyboard;
|
import de.neemann.digital.gui.components.terminal.Keyboard;
|
||||||
import de.neemann.digital.gui.components.terminal.Terminal;
|
import de.neemann.digital.gui.components.terminal.Terminal;
|
||||||
import de.neemann.digital.gui.components.test.TestCaseElement;
|
import de.neemann.digital.testing.TestCaseElement;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -18,7 +18,7 @@ import de.neemann.digital.draw.shapes.ieee.IEEEOrShape;
|
|||||||
import de.neemann.digital.draw.shapes.ieee.IEEEXOrShape;
|
import de.neemann.digital.draw.shapes.ieee.IEEEXOrShape;
|
||||||
import de.neemann.digital.gui.LibrarySelector;
|
import de.neemann.digital.gui.LibrarySelector;
|
||||||
import de.neemann.digital.gui.components.data.DummyElement;
|
import de.neemann.digital.gui.components.data.DummyElement;
|
||||||
import de.neemann.digital.gui.components.test.TestCaseElement;
|
import de.neemann.digital.testing.TestCaseElement;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -28,9 +28,9 @@ import de.neemann.digital.gui.components.data.DataSetDialog;
|
|||||||
import de.neemann.digital.gui.components.expression.ExpressionDialog;
|
import de.neemann.digital.gui.components.expression.ExpressionDialog;
|
||||||
import de.neemann.digital.gui.components.listing.ROMListingDialog;
|
import de.neemann.digital.gui.components.listing.ROMListingDialog;
|
||||||
import de.neemann.digital.gui.components.table.TableDialog;
|
import de.neemann.digital.gui.components.table.TableDialog;
|
||||||
import de.neemann.digital.gui.components.test.DataException;
|
import de.neemann.digital.testing.TestingDataException;
|
||||||
import de.neemann.digital.gui.components.test.TestCaseElement;
|
import de.neemann.digital.testing.TestCaseElement;
|
||||||
import de.neemann.digital.gui.components.test.TestResultDialog;
|
import de.neemann.digital.gui.components.testing.TestResultDialog;
|
||||||
import de.neemann.digital.gui.remote.DigitalHandler;
|
import de.neemann.digital.gui.remote.DigitalHandler;
|
||||||
import de.neemann.digital.gui.remote.RemoteException;
|
import de.neemann.digital.gui.remote.RemoteException;
|
||||||
import de.neemann.digital.gui.remote.RemoteSever;
|
import de.neemann.digital.gui.remote.RemoteSever;
|
||||||
@ -552,7 +552,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
|
|||||||
el.getElementAttributes().getCleanLabel()));
|
el.getElementAttributes().getCleanLabel()));
|
||||||
|
|
||||||
if (tsl.isEmpty())
|
if (tsl.isEmpty())
|
||||||
throw new DataException(Lang.get("err_noTestData"));
|
throw new TestingDataException(Lang.get("err_noTestData"));
|
||||||
|
|
||||||
windowPosManager.register("testresult", new TestResultDialog(Main.this, tsl, circuitComponent.getCircuit(), library)).setVisible(true);
|
windowPosManager.register("testresult", new TestResultDialog(Main.this, tsl, circuitComponent.getCircuit(), library)).setVisible(true);
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ import de.neemann.digital.core.element.Rotation;
|
|||||||
import de.neemann.digital.core.io.IntFormat;
|
import de.neemann.digital.core.io.IntFormat;
|
||||||
import de.neemann.digital.core.memory.DataField;
|
import de.neemann.digital.core.memory.DataField;
|
||||||
import de.neemann.digital.core.memory.ROM;
|
import de.neemann.digital.core.memory.ROM;
|
||||||
import de.neemann.digital.gui.components.test.TestData;
|
import de.neemann.digital.testing.TestData;
|
||||||
import de.neemann.digital.gui.components.test.TestDataEditor;
|
import de.neemann.digital.gui.components.testing.TestDataEditor;
|
||||||
import de.neemann.digital.gui.sync.NoSync;
|
import de.neemann.digital.gui.sync.NoSync;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
import de.neemann.gui.ErrorMessage;
|
import de.neemann.gui.ErrorMessage;
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* Classes to handle test cases
|
|
||||||
*
|
|
||||||
* @author hneemann
|
|
||||||
*/
|
|
||||||
package de.neemann.digital.gui.components.test;
|
|
@ -1,10 +1,12 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.gui.components.testing;
|
||||||
|
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.core.element.Key;
|
import de.neemann.digital.core.element.Key;
|
||||||
import de.neemann.digital.gui.components.CircuitComponent;
|
import de.neemann.digital.gui.components.CircuitComponent;
|
||||||
import de.neemann.digital.gui.components.table.ShowStringDialog;
|
import de.neemann.digital.gui.components.table.ShowStringDialog;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
import de.neemann.digital.testing.TestingDataException;
|
||||||
|
import de.neemann.digital.testing.TestData;
|
||||||
import de.neemann.gui.ErrorMessage;
|
import de.neemann.gui.ErrorMessage;
|
||||||
import de.neemann.gui.ToolTipAction;
|
import de.neemann.gui.ToolTipAction;
|
||||||
|
|
||||||
@ -13,7 +15,7 @@ import java.awt.*;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog to show and edit the test data source.
|
* Dialog to show and edit the testing data source.
|
||||||
*
|
*
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
@ -76,7 +78,7 @@ public class TestDataDialog extends JDialog {
|
|||||||
cc.getCircuit().modified();
|
cc.getCircuit().modified();
|
||||||
cc.getMain().startTests();
|
cc.getMain().startTests();
|
||||||
}
|
}
|
||||||
} catch (DataException e1) {
|
} catch (TestingDataException e1) {
|
||||||
new ErrorMessage(e1.getMessage()).show(TestDataDialog.this);
|
new ErrorMessage(e1.getMessage()).show(TestDataDialog.this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +98,7 @@ public class TestDataDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dispose();
|
dispose();
|
||||||
} catch (DataException e1) {
|
} catch (TestingDataException e1) {
|
||||||
new ErrorMessage(e1.getMessage()).show(TestDataDialog.this);
|
new ErrorMessage(e1.getMessage()).show(TestDataDialog.this);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.gui.components.testing;
|
||||||
|
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.core.element.Key;
|
import de.neemann.digital.core.element.Key;
|
||||||
import de.neemann.digital.gui.Main;
|
import de.neemann.digital.gui.Main;
|
||||||
import de.neemann.digital.gui.components.EditorFactory;
|
import de.neemann.digital.gui.components.EditorFactory;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
import de.neemann.digital.testing.TestData;
|
||||||
import de.neemann.gui.ToolTipAction;
|
import de.neemann.gui.ToolTipAction;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.gui.components.testing;
|
||||||
|
|
||||||
import de.neemann.digital.core.Model;
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.NodeException;
|
||||||
@ -7,6 +7,7 @@ import de.neemann.digital.draw.elements.PinException;
|
|||||||
import de.neemann.digital.draw.library.ElementLibrary;
|
import de.neemann.digital.draw.library.ElementLibrary;
|
||||||
import de.neemann.digital.draw.model.ModelCreator;
|
import de.neemann.digital.draw.model.ModelCreator;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
import de.neemann.digital.testing.*;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
@ -15,7 +16,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog to show the test results.
|
* Dialog to show the testing results.
|
||||||
*
|
*
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
@ -31,10 +32,10 @@ public class TestResultDialog extends JDialog {
|
|||||||
* @param circuit the circuit
|
* @param circuit the circuit
|
||||||
* @param library the library to use
|
* @param library the library to use
|
||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
* @throws DataException DataException
|
* @throws TestingDataException DataException
|
||||||
* @throws PinException PinException
|
* @throws PinException PinException
|
||||||
*/
|
*/
|
||||||
public TestResultDialog(JFrame owner, ArrayList<TestSet> tsl, Circuit circuit, ElementLibrary library) throws NodeException, DataException, PinException {
|
public TestResultDialog(JFrame owner, ArrayList<TestSet> tsl, Circuit circuit, ElementLibrary library) throws NodeException, TestingDataException, PinException {
|
||||||
super(owner, Lang.get("msg_testResult"), false);
|
super(owner, Lang.get("msg_testResult"), false);
|
||||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ public class TestResultDialog extends JDialog {
|
|||||||
|
|
||||||
TestResult tr = new TestResult(ts.data).create(model);
|
TestResult tr = new TestResult(ts.data).create(model);
|
||||||
|
|
||||||
JTable table = new JTable(tr);
|
JTable table = new JTable(new TestResultModel(tr));
|
||||||
table.setDefaultRenderer(MatchedValue.class, new MyRenderer());
|
table.setDefaultRenderer(MatchedValue.class, new MyRenderer());
|
||||||
|
|
||||||
String tabName;
|
String tabName;
|
@ -0,0 +1,70 @@
|
|||||||
|
package de.neemann.digital.gui.components.testing;
|
||||||
|
|
||||||
|
import de.neemann.digital.testing.MatchedValue;
|
||||||
|
import de.neemann.digital.testing.TestResult;
|
||||||
|
|
||||||
|
import javax.swing.event.TableModelListener;
|
||||||
|
import javax.swing.table.TableModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The table model to present a test result.
|
||||||
|
* <p>
|
||||||
|
* Created by hneemann on 24.08.16.
|
||||||
|
*/
|
||||||
|
public class TestResultModel implements TableModel {
|
||||||
|
|
||||||
|
private final TestResult testResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new table model
|
||||||
|
*
|
||||||
|
* @param testResult the testresult to wrap
|
||||||
|
*/
|
||||||
|
public TestResultModel(TestResult testResult) {
|
||||||
|
this.testResult = testResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return testResult.getRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return testResult.getSignalCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int columnIndex) {
|
||||||
|
return testResult.getSignalName(columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getColumnClass(int columnIndex) {
|
||||||
|
return MatchedValue.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
|
return testResult.getResultValue(rowIndex, columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTableModelListener(TableModelListener l) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeTableModelListener(TableModelListener l) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.gui.components.testing;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Classes to handle testing cases
|
||||||
|
*
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.gui.components.testing;
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.core.ObservableValue;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import de.neemann.digital.core.Model;
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.NodeException;
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -42,9 +42,9 @@ public class TestData {
|
|||||||
* Sets the data and checks its validity
|
* Sets the data and checks its validity
|
||||||
*
|
*
|
||||||
* @param data the data
|
* @param data the data
|
||||||
* @throws DataException thrown if data is not valid
|
* @throws TestingDataException thrown if data is not valid
|
||||||
*/
|
*/
|
||||||
public void setDataString(String data) throws DataException {
|
public void setDataString(String data) throws TestingDataException {
|
||||||
if (!data.equals(dataString)) {
|
if (!data.equals(dataString)) {
|
||||||
TestDataParser tdp = new TestDataParser(data).parse();
|
TestDataParser tdp = new TestDataParser(data).parse();
|
||||||
dataString = data;
|
dataString = data;
|
||||||
@ -59,7 +59,7 @@ public class TestData {
|
|||||||
TestDataParser tdp = new TestDataParser(dataString).parse();
|
TestDataParser tdp = new TestDataParser(dataString).parse();
|
||||||
lines = tdp.getLines();
|
lines = tdp.getLines();
|
||||||
names = tdp.getNames();
|
names = tdp.getNames();
|
||||||
} catch (DataException e) {
|
} catch (TestingDataException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
@ -37,9 +37,9 @@ public class TestDataParser {
|
|||||||
* The data then can be found in lines and names.
|
* The data then can be found in lines and names.
|
||||||
*
|
*
|
||||||
* @return this for chained calls
|
* @return this for chained calls
|
||||||
* @throws DataException DataException
|
* @throws TestingDataException DataException
|
||||||
*/
|
*/
|
||||||
public TestDataParser parse() throws DataException {
|
public TestDataParser parse() throws TestingDataException {
|
||||||
try {
|
try {
|
||||||
String header = readNonEmptyLine(r);
|
String header = readNonEmptyLine(r);
|
||||||
if (header != null) {
|
if (header != null) {
|
||||||
@ -55,18 +55,18 @@ public class TestDataParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new DataException(e);
|
throw new TestingDataException(e);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addLine(String line) throws DataException {
|
private void addLine(String line) throws TestingDataException {
|
||||||
StringTokenizer tok;
|
StringTokenizer tok;
|
||||||
tok = new StringTokenizer(line);
|
tok = new StringTokenizer(line);
|
||||||
Value[] row = new Value[names.size()];
|
Value[] row = new Value[names.size()];
|
||||||
int cols = tok.countTokens();
|
int cols = tok.countTokens();
|
||||||
if (cols != names.size())
|
if (cols != names.size())
|
||||||
throw new DataException(Lang.get("err_testDataExpected_N0_found_N1_numbersInLine_N2", names.size(), cols, lineNumber));
|
throw new TestingDataException(Lang.get("err_testDataExpected_N0_found_N1_numbersInLine_N2", names.size(), cols, lineNumber));
|
||||||
|
|
||||||
for (int i = 0; i < cols; i++) {
|
for (int i = 0; i < cols; i++) {
|
||||||
String numStr = null;
|
String numStr = null;
|
||||||
@ -74,7 +74,7 @@ public class TestDataParser {
|
|||||||
numStr = tok.nextToken();
|
numStr = tok.nextToken();
|
||||||
row[i] = new Value(numStr);
|
row[i] = new Value(numStr);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new DataException(Lang.get("err_notANumber_N0_inLine_N1", numStr, lineNumber));
|
throw new TestingDataException(Lang.get("err_notANumber_N0_inLine_N1", numStr, lineNumber));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lines.add(row);
|
lines.add(row);
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import de.neemann.digital.core.Model;
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.NodeException;
|
||||||
@ -7,18 +7,15 @@ import de.neemann.digital.core.Signal;
|
|||||||
import de.neemann.digital.core.wiring.Clock;
|
import de.neemann.digital.core.wiring.Clock;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
import javax.swing.event.TableModelListener;
|
|
||||||
import javax.swing.table.TableModel;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the test results created by a single {@link TestData} instance.
|
* Stores the test results created by a single {@link TestData} instance.
|
||||||
* The class also performs the tests.
|
* The class also performs the tests.
|
||||||
* Implemements {@link TableModel}, so the result can easily be shown in a {@link javax.swing.JTable}.
|
|
||||||
*
|
*
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class TestResult implements TableModel {
|
public class TestResult {
|
||||||
|
|
||||||
private final ArrayList<String> names;
|
private final ArrayList<String> names;
|
||||||
private final ArrayList<Value[]> lines;
|
private final ArrayList<Value[]> lines;
|
||||||
@ -26,9 +23,9 @@ public class TestResult implements TableModel {
|
|||||||
private boolean allPassed;
|
private boolean allPassed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new test result
|
* Creates a new testing result
|
||||||
*
|
*
|
||||||
* @param testData the test data
|
* @param testData the testing data
|
||||||
*/
|
*/
|
||||||
public TestResult(TestData testData) {
|
public TestResult(TestData testData) {
|
||||||
names = testData.getNames();
|
names = testData.getNames();
|
||||||
@ -37,14 +34,14 @@ public class TestResult implements TableModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the result by comparing the test vector with the given model-
|
* Creates the result by comparing the testing vector with the given model-
|
||||||
*
|
*
|
||||||
* @param model the model to check
|
* @param model the model to check
|
||||||
* @return this for chained calls
|
* @return this for chained calls
|
||||||
* @throws DataException DataException
|
* @throws TestingDataException DataException
|
||||||
* @throws NodeException NodeException
|
* @throws NodeException NodeException
|
||||||
*/
|
*/
|
||||||
public TestResult create(Model model) throws DataException, NodeException {
|
public TestResult create(Model model) throws TestingDataException, NodeException {
|
||||||
allPassed = true;
|
allPassed = true;
|
||||||
ArrayList<TestSignal> inputs = new ArrayList<>();
|
ArrayList<TestSignal> inputs = new ArrayList<>();
|
||||||
for (Signal s : model.getInputs())
|
for (Signal s : model.getInputs())
|
||||||
@ -62,35 +59,32 @@ public class TestResult implements TableModel {
|
|||||||
|
|
||||||
Value[] res = new Value[row.length];
|
Value[] res = new Value[row.length];
|
||||||
|
|
||||||
boolean isClockValue = false;
|
boolean clockIsUsed = false;
|
||||||
|
// set all values except the clocks
|
||||||
for (TestSignal in : inputs) {
|
for (TestSignal in : inputs) {
|
||||||
if (row[in.index].getType() != Value.Type.CLOCK) {
|
if (row[in.index].getType() != Value.Type.CLOCK) {
|
||||||
row[in.index].setTo(in.value);
|
row[in.index].copyTo(in.value);
|
||||||
} else {
|
} else {
|
||||||
isClockValue = true;
|
clockIsUsed = true;
|
||||||
}
|
}
|
||||||
res[in.index] = row[in.index];
|
res[in.index] = row[in.index];
|
||||||
}
|
}
|
||||||
if (isClockValue) {
|
|
||||||
|
|
||||||
|
if (clockIsUsed) { // a clock signal is used
|
||||||
model.doStep(); // propagate all except clock
|
model.doStep(); // propagate all except clock
|
||||||
|
|
||||||
for (TestSignal in : inputs) {
|
// set clock
|
||||||
if (row[in.index].getType() == Value.Type.CLOCK) {
|
for (TestSignal in : inputs)
|
||||||
row[in.index].setTo(in.value);
|
if (row[in.index].getType() == Value.Type.CLOCK)
|
||||||
}
|
row[in.index].copyTo(in.value);
|
||||||
}
|
|
||||||
|
|
||||||
model.doStep(); // propagate clock high
|
// propagate clock change
|
||||||
|
model.doStep();
|
||||||
|
|
||||||
for (TestSignal in : inputs) { // reset clock values
|
// restore clock
|
||||||
if (row[in.index].getType() == Value.Type.CLOCK) {
|
for (TestSignal in : inputs) // invert the clock values
|
||||||
if (row[in.index].getValue() != 0)
|
if (row[in.index].getType() == Value.Type.CLOCK)
|
||||||
in.value.set(0, false);
|
in.value.setBool(!in.value.getBool());
|
||||||
else
|
|
||||||
in.value.set(1, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model.doStep();
|
model.doStep();
|
||||||
@ -114,16 +108,51 @@ public class TestResult implements TableModel {
|
|||||||
return allPassed;
|
return allPassed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getIndexOf(String name) throws DataException {
|
private int getIndexOf(String name) throws TestingDataException {
|
||||||
if (name == null || name.length() == 0)
|
if (name == null || name.length() == 0)
|
||||||
throw new DataException(Lang.get("err_unnamedSignal", name));
|
throw new TestingDataException(Lang.get("err_unnamedSignal", name));
|
||||||
|
|
||||||
for (int i = 0; i < names.size(); i++) {
|
for (int i = 0; i < names.size(); i++) {
|
||||||
String n = names.get(i);
|
String n = names.get(i);
|
||||||
if (n.equals(name))
|
if (n.equals(name))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
throw new DataException(Lang.get("err_signal_N_notInTextVector", name));
|
throw new TestingDataException(Lang.get("err_signal_N_notInTestVector", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the number of rows
|
||||||
|
*/
|
||||||
|
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestSignal {
|
private static class TestSignal {
|
||||||
@ -136,56 +165,4 @@ public class TestResult implements TableModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getRowCount() {
|
|
||||||
return results.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnCount() {
|
|
||||||
return names.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColumnName(int columnIndex) {
|
|
||||||
return names.get(columnIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> getColumnClass(int columnIndex) {
|
|
||||||
return MatchedValue.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
|
||||||
return getValue(rowIndex, columnIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the typed value
|
|
||||||
*
|
|
||||||
* @param rowIndex rowIndex
|
|
||||||
* @param columnIndex columnIndex
|
|
||||||
* @return the value
|
|
||||||
*/
|
|
||||||
public Value getValue(int rowIndex, int columnIndex) {
|
|
||||||
return results.get(rowIndex)[columnIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTableModelListener(TableModelListener l) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeTableModelListener(TableModelListener l) {
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,15 +1,15 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
public class DataException extends Exception {
|
public class TestingDataException extends Exception {
|
||||||
/**
|
/**
|
||||||
* creates a new instance
|
* creates a new instance
|
||||||
*
|
*
|
||||||
* @param cause the cause
|
* @param cause the cause
|
||||||
*/
|
*/
|
||||||
public DataException(Exception cause) {
|
public TestingDataException(Exception cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ public class DataException extends Exception {
|
|||||||
*
|
*
|
||||||
* @param message the message
|
* @param message the message
|
||||||
*/
|
*/
|
||||||
public DataException(String message) {
|
public TestingDataException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import de.neemann.digital.core.ObservableValue;
|
import de.neemann.digital.core.ObservableValue;
|
||||||
|
|
||||||
@ -130,11 +130,11 @@ public class Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets this value to a copy of the given {@link ObservableValue}
|
* Sets this value to the given {@link ObservableValue}
|
||||||
*
|
*
|
||||||
* @param ov the ObservableValue to copy
|
* @param ov the ObservableValue to update
|
||||||
*/
|
*/
|
||||||
public void setTo(ObservableValue ov) {
|
public void copyTo(ObservableValue ov) {
|
||||||
ov.set(value, isHighZ());
|
ov.set(value, isHighZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
10
src/main/java/de/neemann/digital/testing/package-info.java
Normal file
10
src/main/java/de/neemann/digital/testing/package-info.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Classes used to test a circuit.
|
||||||
|
* You can add a test to a circuit like a regular gate.
|
||||||
|
* There you can edit the test case and this test case can be run and the expected results are
|
||||||
|
* compared with the calculated results.
|
||||||
|
* It's somewhat like a unit test in java, but less flexible at the moment.
|
||||||
|
*
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.testing;
|
@ -181,7 +181,7 @@ Zur Analyse können Sie die Schaltung im Gatterschrittmodus ausführen.</string>
|
|||||||
<string name="err_parserUnexpectedEndOfExpression">Unerwartetes Ende des Ausdrucks</string>
|
<string name="err_parserUnexpectedEndOfExpression">Unerwartetes Ende des Ausdrucks</string>
|
||||||
<string name="err_notANumber_N0_inLine_N1">Wert {0} in Zeile {1} ist keine Zahl!</string>
|
<string name="err_notANumber_N0_inLine_N1">Wert {0} in Zeile {1} ist keine Zahl!</string>
|
||||||
<string name="err_testDataExpected_N0_found_N1_numbersInLine_N2">Erwarte {0} anstelle von {1} Werten in Zeile {2}!</string>
|
<string name="err_testDataExpected_N0_found_N1_numbersInLine_N2">Erwarte {0} anstelle von {1} Werten in Zeile {2}!</string>
|
||||||
<string name="err_signal_N_notInTextVector">Signal {0} ist im Testvektor nicht vorhanden!</string>
|
<string name="err_signal_N_notInTestVector">Signal {0} ist im Testvektor nicht vorhanden!</string>
|
||||||
<string name="err_noTestData">Keine Testdaten vorhanden.</string>
|
<string name="err_noTestData">Keine Testdaten vorhanden.</string>
|
||||||
<string name="err_unnamedSignal">Es gibt ein unbenanntes Signal</string>
|
<string name="err_unnamedSignal">Es gibt ein unbenanntes Signal</string>
|
||||||
<string name="key_AddrBits">Adress Bits</string>
|
<string name="key_AddrBits">Adress Bits</string>
|
||||||
|
@ -181,7 +181,7 @@ To analyse you can run the circuit in single gate step mode.</string>
|
|||||||
<string name="err_parserUnexpectedEndOfExpression">Unexpected end of expression</string>
|
<string name="err_parserUnexpectedEndOfExpression">Unexpected end of expression</string>
|
||||||
<string name="err_notANumber_N0_inLine_N1">Value {0} in line {1} is not a number!</string>
|
<string name="err_notANumber_N0_inLine_N1">Value {0} in line {1} is not a number!</string>
|
||||||
<string name="err_testDataExpected_N0_found_N1_numbersInLine_N2">Expected {0} but found {1} values in line {2}!</string>
|
<string name="err_testDataExpected_N0_found_N1_numbersInLine_N2">Expected {0} but found {1} values in line {2}!</string>
|
||||||
<string name="err_signal_N_notInTextVector">Signal {0} is not present in test vector!</string>
|
<string name="err_signal_N_notInTestVector">Signal {0} is not present in test vector!</string>
|
||||||
<string name="err_noTestData">Not test data found.</string>
|
<string name="err_noTestData">Not test data found.</string>
|
||||||
<string name="err_unnamedSignal">There is a unnamed signal!</string>
|
<string name="err_unnamedSignal">There is a unnamed signal!</string>
|
||||||
<string name="key_AddrBits">Address Bits</string>
|
<string name="key_AddrBits">Address Bits</string>
|
||||||
|
@ -8,6 +8,7 @@ import java.io.File;
|
|||||||
* Reads all examples and tries to create the model.
|
* Reads all examples and tries to create the model.
|
||||||
* Makes sure that all examples are creatable (one can build the model)
|
* Makes sure that all examples are creatable (one can build the model)
|
||||||
* Does not ensure that they work correctly!
|
* Does not ensure that they work correctly!
|
||||||
|
* Correctness is tested by {@link TestTestableExamples}.
|
||||||
*
|
*
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
|
@ -3,9 +3,9 @@ package de.neemann.digital.integration;
|
|||||||
import de.neemann.digital.core.Model;
|
import de.neemann.digital.core.Model;
|
||||||
import de.neemann.digital.draw.elements.VisualElement;
|
import de.neemann.digital.draw.elements.VisualElement;
|
||||||
import de.neemann.digital.draw.model.ModelCreator;
|
import de.neemann.digital.draw.model.ModelCreator;
|
||||||
import de.neemann.digital.gui.components.test.TestCaseElement;
|
import de.neemann.digital.testing.TestCaseElement;
|
||||||
import de.neemann.digital.gui.components.test.TestData;
|
import de.neemann.digital.testing.TestData;
|
||||||
import de.neemann.digital.gui.components.test.TestResult;
|
import de.neemann.digital.testing.TestResult;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ import junit.framework.TestCase;
|
|||||||
*/
|
*/
|
||||||
public class TestDataParserTest extends TestCase {
|
public class TestDataParserTest extends TestCase {
|
||||||
|
|
||||||
public void testOk() throws DataException {
|
public void testOk() throws TestingDataException {
|
||||||
TestDataParser td = new TestDataParser("A B\n0 1\n1 0\nX x").parse();
|
TestDataParser td = new TestDataParser("A B\n0 1\n1 0\nX x").parse();
|
||||||
assertEquals(2,td.getNames().size());
|
assertEquals(2,td.getNames().size());
|
||||||
assertEquals(3,td.getLines().size());
|
assertEquals(3,td.getLines().size());
|
||||||
@ -32,7 +32,7 @@ public class TestDataParserTest extends TestCase {
|
|||||||
try {
|
try {
|
||||||
new TestDataParser("A B\n0 0\n1").parse();
|
new TestDataParser("A B\n0 0\n1").parse();
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (DataException e) {
|
} catch (TestingDataException e) {
|
||||||
assertTrue(true);
|
assertTrue(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ public class TestDataParserTest extends TestCase {
|
|||||||
try {
|
try {
|
||||||
new TestDataParser("A B\n0 0\n1 u").parse();
|
new TestDataParser("A B\n0 0\n1 u").parse();
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (DataException e) {
|
} catch (TestingDataException e) {
|
||||||
assertTrue(true);
|
assertTrue(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ public class TestDataTest extends TestCase {
|
|||||||
try {
|
try {
|
||||||
td.setDataString(DATA3);
|
td.setDataString(DATA3);
|
||||||
assertTrue(false);
|
assertTrue(false);
|
||||||
} catch (DataException e) {
|
} catch (TestingDataException e) {
|
||||||
assertTrue(true);
|
assertTrue(true);
|
||||||
}
|
}
|
||||||
// TestData remains unchanged!
|
// TestData remains unchanged!
|
@ -1,4 +1,4 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
import de.neemann.digital.analyse.expression.Expression;
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
import de.neemann.digital.analyse.parser.ParseException;
|
import de.neemann.digital.analyse.parser.ParseException;
|
||||||
@ -17,6 +17,9 @@ import junit.framework.TestCase;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import static de.neemann.digital.analyse.expression.Not.not;
|
||||||
|
import static de.neemann.digital.analyse.expression.Variable.v;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hneemann
|
* @author hneemann
|
||||||
*/
|
*/
|
||||||
@ -55,10 +58,10 @@ public class TestResultTest extends TestCase {
|
|||||||
+ "1 1 0\n");
|
+ "1 1 0\n");
|
||||||
TestResult tr = new TestResult(data).create(model);
|
TestResult tr = new TestResult(data).create(model);
|
||||||
assertFalse(tr.allPassed());
|
assertFalse(tr.allPassed());
|
||||||
assertEquals(true, ((MatchedValue)tr.getValue(0,2)).isPassed());
|
assertEquals(true, ((MatchedValue) tr.getResultValue(0, 2)).isPassed());
|
||||||
assertEquals(true, ((MatchedValue)tr.getValue(1,2)).isPassed());
|
assertEquals(true, ((MatchedValue) tr.getResultValue(1, 2)).isPassed());
|
||||||
assertEquals(true, ((MatchedValue)tr.getValue(2,2)).isPassed());
|
assertEquals(true, ((MatchedValue) tr.getResultValue(2, 2)).isPassed());
|
||||||
assertEquals(false, ((MatchedValue)tr.getValue(3,2)).isPassed());
|
assertEquals(false, ((MatchedValue) tr.getResultValue(3, 2)).isPassed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testResultDontCare() throws Exception {
|
public void testResultDontCare() throws Exception {
|
@ -1,5 +1,6 @@
|
|||||||
package de.neemann.digital.gui.components.test;
|
package de.neemann.digital.testing;
|
||||||
|
|
||||||
|
import de.neemann.digital.testing.Value;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,5 +44,6 @@ public class ValueTest extends TestCase {
|
|||||||
assertEquals("X",new Value("X").toString());
|
assertEquals("X",new Value("X").toString());
|
||||||
assertEquals("Z",new Value("Z").toString());
|
assertEquals("Z",new Value("Z").toString());
|
||||||
assertEquals("2",new Value("2").toString());
|
assertEquals("2",new Value("2").toString());
|
||||||
|
assertEquals("C",new Value("C").toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user