Skip to content

Commit

Permalink
Add tests for parsing DM vertices
Browse files Browse the repository at this point in the history
* Tests are parameterized so that we test both the old and new parser code
* Fix infinite while-loop issue in the old parser's `getWord`; `Reader#ready`
indicates that `read` would be non-blocking, not that read would return new
data. To find the end of the reader's data we have to watch for `-1` returned by
`read`.
* Get rid of deprecated `new Float(num)` call
* Add getters for high/low in the range vertex classes for testing. We can
test the string representation if we write tests for the individual classes,
but for testing parsing checking the field values is more appropriate.

We have to disable one test currently because the new parsing code fails it.
  • Loading branch information
garfieldnate committed Sep 5, 2024
1 parent 68a1ca2 commit ebe1724
Show file tree
Hide file tree
Showing 8 changed files with 747 additions and 536 deletions.
9 changes: 5 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ repositories {

dependencies {
implementation("org.jetbrains:annotations:24.0.0")
testImplementation(libs.junit.jupiter)
testImplementation("org.mockito:mockito-core:5.12.0")

testRuntimeOnly("org.junit.platform:junit-platform-launcher")
// load all the jars in the lib/ folder
implementation(fileTree("lib") {
include("*.jar")
})

testImplementation(libs.junit.jupiter)
testImplementation("org.mockito:mockito-core:5.12.0")
// testImplementation("org.junit.jupiter:junit-jupiter-params")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

// For loading the SML JNI library
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class SoarWorkingMemoryReader {
*
* Note: will recurse for foreign nodes
*/
private static SoarVertex readVertex(Reader fr) throws IOException {
static SoarVertex readVertex(Reader fr) throws IOException {
String type = ReaderUtils.getWord(fr);
SoarVertex vertexToAdd = null;
int id = ReaderUtils.getInteger(fr);
Expand Down Expand Up @@ -131,26 +131,21 @@ public static void read(SoarWorkingMemoryModel swmm, Reader fr, Reader cr) throw
*
* @return a SoarVertex object or null on failure
*/
private static SoarVertex readVertexSafe(String line, int expectedId, Vector<FeedbackListEntry> errors) {
static SoarVertex readVertexSafe(String line, int expectedId, Vector<FeedbackListEntry> errors) {
//Any vertex definition must have at least two words
if (line == null) return null;
if (line.trim().length() == 0) return null;
String[] words = line.split("[ \\t]"); //split on spaces and tabs
// split on spaces and tabs; rest will require further parsing
String[] words = line.split("[ \\t]");//, 3);
if (words.length < 2) {
errors.add(new FeedbackListEntry("Error: truncated datamap entry: " + line));
return null;
}
// String rest = words[2];

//Verify a valid type
boolean valid = false;
String vertexType = words[0];
for(String validType : SoarVertex.VERTEX_TYPES) {
if (validType.equals(vertexType)) {
valid = true;
break;
}
}
if (! valid) {
if (!SoarVertex.VERTEX_TYPES.contains(vertexType)) {
errors.add(new FeedbackListEntry("Error: datamap entry has invalid type: " + line));
return null;
}
Expand All @@ -161,7 +156,7 @@ private static SoarVertex readVertexSafe(String line, int expectedId, Vector<Fee
id = Integer.parseInt(words[1]);
}
catch(NumberFormatException nfe) {
/* nothing to do here */
/* handled below */
}
if (id < 0) {
errors.add(new FeedbackListEntry("Error: datamap entry has invalid id: " + line));
Expand Down
226 changes: 117 additions & 109 deletions src/main/java/edu/umich/soar/visualsoar/graph/FloatRangeVertex.java
Original file line number Diff line number Diff line change
@@ -1,109 +1,117 @@
package edu.umich.soar.visualsoar.graph;

import edu.umich.soar.visualsoar.dialogs.EditNumberDialog;

public class FloatRangeVertex extends SoarVertex {
private static final long serialVersionUID = 20221225L;

//////////////////////////////////////////
// Data Members
//////////////////////////////////////////
private double low, high;
String rep;

//////////////////////////////////////////
// Constructors
//////////////////////////////////////////
public FloatRangeVertex(int id, double _low, double _high) {
super(id);
if (low > high) {
throw new IllegalArgumentException("Low cannot be greater than high");
}
low = _low;
high = _high;
rep = ": float" + getRangeString();
}

//////////////////////////////////////////
// Accessors
//////////////////////////////////////////
@Override
public boolean allowsEmanatingEdges() {
return false;
}

@Override
public boolean isEditable() {
return true;
}

@Override
public boolean isValid(String s) {
try {
float f = Float.parseFloat(s);
return f >= low && f <= high;
} catch (NumberFormatException nfe) {
return false;
}
}

@Override
public SoarVertex copy(int newId) {
return new FloatRangeVertex(newId, low, high);
}

@Override
public String typeName() { return "float"; }

@Override
public String toString() {
return rep;
}

//////////////////////////////////////////
// Manipulators
//////////////////////////////////////////
public boolean edit(java.awt.Frame owner) {
EditNumberDialog theDialog = new EditNumberDialog(owner, "Float");
theDialog.setLow(new Float(low));
theDialog.setHigh(new Float(high));
theDialog.setVisible(true);

if (theDialog.wasApproved()) {
low = theDialog.getLow().floatValue();
high = theDialog.getHigh().floatValue();
rep = ": float" + getRangeString();
return true;
}
return false;
}

@Override
public void write(java.io.Writer w) throws java.io.IOException {
w.write("FLOAT_RANGE " + number + " " + low + " " + high + '\n');
}

/** creates a string representing this integer's range.
* If there is no limit then an empty string is returned */
public String getRangeString() {
String result = "";
if (low != Float.NEGATIVE_INFINITY || high != Float.POSITIVE_INFINITY) {
result += " [ ";
if (low == Float.NEGATIVE_INFINITY) {
result += "... ";
} else {
result += low + " ";
}
result += "- ";
if (high == Float.POSITIVE_INFINITY) {
result += "... ";
} else {
result += high + " ";
}
result += " ]";
}
return result;
}


}
package edu.umich.soar.visualsoar.graph;

import edu.umich.soar.visualsoar.dialogs.EditNumberDialog;

public class FloatRangeVertex extends SoarVertex {
private static final long serialVersionUID = 20221225L;

//////////////////////////////////////////
// Data Members
//////////////////////////////////////////
private double low, high;
String rep;

//////////////////////////////////////////
// Constructors
//////////////////////////////////////////
public FloatRangeVertex(int id, double low, double high) {
super(id);
if (low > high) {
throw new IllegalArgumentException("Low cannot be greater than high");
}
this.low = low;
this.high = high;
rep = ": float" + getRangeString();
}

//////////////////////////////////////////
// Accessors
//////////////////////////////////////////
@Override
public boolean allowsEmanatingEdges() {
return false;
}

@Override
public boolean isEditable() {
return true;
}

@Override
public boolean isValid(String s) {
try {
float f = Float.parseFloat(s);
return f >= low && f <= high;
} catch (NumberFormatException nfe) {
return false;
}
}

@Override
public SoarVertex copy(int newId) {
return new FloatRangeVertex(newId, low, high);
}

@Override
public String typeName() { return "float"; }

@Override
public String toString() {
return rep;
}

//////////////////////////////////////////
// Manipulators
//////////////////////////////////////////
public boolean edit(java.awt.Frame owner) {
EditNumberDialog theDialog = new EditNumberDialog(owner, "Float");
theDialog.setLow((float) low);
theDialog.setHigh((float) high);
theDialog.setVisible(true);

if (theDialog.wasApproved()) {
low = theDialog.getLow().floatValue();
high = theDialog.getHigh().floatValue();
rep = ": float" + getRangeString();
return true;
}
return false;
}

@Override
public void write(java.io.Writer w) throws java.io.IOException {
w.write("FLOAT_RANGE " + number + " " + low + " " + high + '\n');
}

public double getLow() {
return low;
}

public double getHigh() {
return high;
}

/** creates a string representing this integer's range.
* If there is no limit then an empty string is returned */
public String getRangeString() {
String result = "";
if (low != Float.NEGATIVE_INFINITY || high != Float.POSITIVE_INFINITY) {
result += " [ ";
if (low == Float.NEGATIVE_INFINITY) {
result += "... ";
} else {
result += low + " ";
}
result += "- ";
if (high == Float.POSITIVE_INFINITY) {
result += "... ";
} else {
result += high + " ";
}
result += " ]";
}
return result;
}


}
Loading

0 comments on commit ebe1724

Please sign in to comment.