Last time I blogged about one of the cooler features I've been working on, the automatic testing framework to which I just committed some technical changes. This is still work in progress but the general direction is pretty solid and I think we can start discussing it.
The general idea behind these features is to enable debugging using very little code, so we can build a debug version of the application without changing application code and thus automate testing of this application. The code exists in DebugController and it essentially replaces the underlying implementation class with an internal DebugImplementation, the controller is far more capable as an API than a simple recorder, it allows Java based automation and testing allowing you to write unit tests in Java for your applications. To use the debug controller you must avoid Display.init(this) and instead call DebugController.init and everything should work as expected.... Sort of...
If you use the standard DebugController.init(this) method you won't get the automated script recording feature demoed previously, unlike Display's init method the debug controller accepts another argument: ScriptStore.
A ScriptStore is a model for storing recorded scripts thus allowing the developer (you) to store your scripts anywhere you want. Why didn't we provide a default implementation of this???
Well:
1. RMS exists only in MIDP (not in CDC).
2. GCF isn't always supported in the same way and might require permissions.
3. Networking needs a server component or storage space.
However, for you this should be pretty easy since it allows you to store your scripts on the server side for sharing between phones or on the device itself for fast access (just like you would expect from MVC!). To ease your life a bit here is a simple RMS based implementation of such a store use with caution since the format of the underlying scripts is sure to change in the future so don't grow too invested.
class RMSStore implements DebugController.ScriptStore {
private ListModel model;
public ListModel getStoredScriptNameList() throws IOException {
if(model == null) {
try {
RecordStore r = RecordStore.openRecordStore("scriptNames", true);
RecordEnumeration e = r.enumerateRecords(null, null, false);
Vector result = new Vector();
while (e.hasNextElement()) {
String s = new String(e.nextRecord());
result.addElement(s);
}
e.destroy();
r.closeRecordStore();
model = new DefaultListModel(result);
} catch (RecordStoreException ex) {
ex.printStackTrace();
throw new IOException(ex.getMessage());
}
}
return model;
}
public void storeScript(Script s) throws IOException {
try {
if(model != null) {
model.addItem(s.getTitle());
}
RecordStore r = RecordStore.openRecordStore("scriptNames", true);
byte[] b = s.getTitle().getBytes();
r.addRecord(b, 0, b.length);
r.closeRecordStore();
r = RecordStore.openRecordStore("script-" + s.getTitle(), true);
b = DebugController.scriptToBytes(s);
r.addRecord(b, 0, b.length);
r.closeRecordStore();
} catch (RecordStoreException ex) {
ex.printStackTrace();
throw new IOException(ex.getMessage());
}
}
public Script loadScript(String name) throws IOException {
try {
RecordStore r = RecordStore.openRecordStore("script-" + name, true);
RecordEnumeration e = r.enumerateRecords(null, null, false);
Script s = DebugController.scriptFromBytes(e.nextRecord());
e.destroy();
r.closeRecordStore();
return s;
} catch (RecordStoreException ex) {
ex.printStackTrace();
throw new IOException(ex.getMessage());
}
}
public void deleteScript(String name) throws IOException {
try {
if(model != null) {
for(int iter = 0 ; iter < model.getSize() ; iter++) {
if(model.getItemAt(iter).equals(name)) {
model.removeItem(iter);
}
}
}
RecordStore.deleteRecordStore("script-" + name);
RecordStore r = RecordStore.openRecordStore("scriptNames", true);
RecordEnumeration e = r.enumerateRecords(null, null, false);
while(e.hasNextElement()) {
int id = e.nextRecordId();
String entry = new String(r.getRecord(id));
if(entry.equals(name)) {
r.deleteRecord(id);
break;
}
}
e.destroy();
r.closeRecordStore();
} catch (RecordStoreException ex) {
ex.printStackTrace();
throw new IOException(ex.getMessage());
}
}
}
0 comments:
Post a Comment