Making methods replayable
To make a method in your project capable of being "replayed" you must invoke the Runabout Service and capture the JSON output.
Invoking the RunaboutService
The main entrypoint into the Runabout library is the RunaboutService
interface. You can get the default implementation of this interface via:
RunaboutService.getService()
It contains multiple methods like toRunaboutString
and toRunaboutJson
which take in any number of Objects and return either a JSON object or a Stringified version of that JSON object.
This JSON output is what the Runabout IDE plugin uses to rerun the scenario in your IDE.
To ensure the scenario can be recreated completely, you must call into the runabout service with all argument variables (and the instance if an instance method).
Exporting / Logging Runabout JSON Output
The Runabout library currently does not provide any logging utitilies. Instead, it is preffered that you use your existing logging infrastructure to collect and store the messages created by the RunaboutService at runtime.
Example
This example shows a simple method which uses a logger to report the RunaboutService's JSON output.
Notice how the service is invoked:
service.toRunaboutString(this, member, skillLevel)
Full class example:
package com.example;
import dev.runabout.RunaboutInput;
import dev.runabout.RunaboutService;
import dev.runabout.ToRunabout;
import java.util.Map;
import java.util.logging.Logger;
public class Team {
private static final Logger LOGGER = Logger.getLogger();
private final String name;
private final Map<String, Integer> members;
public Team(String name, Map<String, Integer> members) {
this.name = name;
this.members = members;
}
public void addSkillToMember(String member, int skillLevel) {
LOGGER.info(() -> RunaboutService.getService().toRunaboutString(this, member, skillLevel));
int total = skillLevel;
Integer current = members.get(member);
if (current != null) {
total += current;
}
members.put(member, total);
}
@ToRunabout
RunaboutInput toRunabout() {
// The meaning of this is covered in the next docs page.
final RunaboutInput input1 = RunaboutService.getService().serialize(name);
final RunaboutInput input2 = RunaboutService.getService().serialize(members);
final String eval = "new Team(" + input1.getEval() + ", " + input2.getEval() + ")";
final Set<String> dependencies = new HashSet<>();
dependencies.addAll(input1.getDependencies());
dependencies.addAll(input2.getDependencies());
dependencies.add(Team.class.getCanonicalName());
return RunaboutInput.of(eval, dependencies);
}
}
If INFO
level logging is enabled, an invocation to addSkillToMember
will produce the following JSON output in the logs:
{
"datetime": "2024-03-12T00:07:30.852250Z",
"method": "com.example.Team#addMember(java.lang.String, int)",
"inputs": [
{
"type": "com.example.Team",
"eval": "new Team(\"Chicago Bulls\", new HashMap<>() {{ put(\"Scottie Pippen\", (int) 100); }})",
"dependencies": [
"java.util.HashMap",
"com.example.Team"
]
},
{
"type": "java.lang.String",
"eval": "\"Michael Jordan\"",
"dependencies": []
},
{
"type": "java.lang.Integer",
"eval": "(int) 200",
"dependencies":[]}
],
"version": "1.1.0"
}