src/main/java/smartrics/rest/fitnesse/fixture/FitRow.java
if (row != null) {
            return row.size();
int size()
String hostName  String pictureData
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
this.pictureData = pictureData;
        this.initialised = false;
    public RestFixtureWithSeq(String hostName, String configName, String pictureData) {
        this.pictureData = pictureData;
        this.initialised = false;
    public RestFixtureWithSeq(PartsFactory partsFactory, String hostName, String configName, String pictureData) {
        this.pictureData = pictureData;
        this.initialised = false;
public RestFixtureWithSeq(String hostName, String pictureData)
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
cell = row.getCell(1);
        byte[] content = PictureGenerator.generate(model.toString(), parseAttributes(cell.body()), "template.svg", format);
        cell.body("<img src=\"data:image/" + format + ";base64," + new String(Base64.encode(content)) + "\" />");
void embed()
Model model
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
this.model = model;
        initializeFields();
        createSequenceModel();
        initialised = true;
        if (!graphFileDir.exists()) {
            if (!graphFileDir.mkdirs()) {
        myFixtureListener = new MyFixtureListener(new File(graphFileDir, this.getPictureName()).getAbsolutePath(), model, attributes);
        setFixtureListener(myFixtureListener);
    protected String getPictureDataFromArgs() {
        return getBaseUrl() != null && pictureData != null;
            throw new FitFailureException("Both baseUrl and picture data (containing the picture name) need to be passed to the fixture");
    protected void createSequenceModel() {
        if (!initialised) {
            LOG.info("Initialising sequence model");
            this.model = new SequenceModel();
void setModel(Model model)
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
super.setBody();
void setBody()
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
super.comment();
        @SuppressWarnings("rawtypes")
        CellWrapper messageCell = row.getCell(1);
        String body = messageCell.body();
        String plainBody = Tools.fromHtml(body).trim();
        model.comment(plainBody);
        String res = getResource();
        String args = getLastRequest().getQuery();
        String ret = "status=" + getLastResponse().getStatusCode().toString();
        model.get(res, args, ret);
        String res = getResource();
        String id = getIdFromLocationHeader();
        // could ever be that the POST to /abc returns a location of /qwe/1 ??
        String result = String.format("id=%s, status=%s", id, getLastResponse().getStatusCode().toString());
        String args = getLastRequest().getQuery();
        model.post(res, args, result);
        String res = getResource();
        String args = getLastRequest().getQuery();
        String ret = "status=" + getLastResponse().getStatusCode().toString();
        model.put(res, args, ret);
    void setFixtureListener(FixtureListener l) {
        super.listener = l;
    private static String getPictureFormat(String pictureName) {
        int pos = pictureName.indexOf(".");
        if (pos >= 0) {
            return pictureName.substring(pos + 1).toLowerCase();
void comment()
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
if (!initialised) {
            String data = pictureData;
            LOG.info("Picture data = " + pictureData);
            int[] pos = getPositionOfNextOfTokenOptionallyInDoubleQuotes(data);
            this.pictureName = data.substring(pos[0], pos[1]);
            LOG.info("Found picture name: " + pictureName);
            if (pos[1] < data.length()) {
                data = data.substring(pos[1] + 1);
                this.attributes = parseAttributes(data);
void initializeFields()
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
List<Header> list = getLastResponse().getHeader("Location");
        String location = "";
        if (list != null && !list.isEmpty()) {
            location = list.get(0).getValue();
        String[] parts = guessParts(location);
        return parts[1];
String getIdFromLocationHeader()
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
String res = getLastRequest().getResource();
        if (res.endsWith("/")) {
            res = res.substring(0, res.length() - 1);
        return res;
String getResource()
String text
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
root.add(new Node(new Note(Tools.fromHtml(text))));
void comment(String text)
String resource  String query  String result
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
message(Message.SYNC, resource, "GET", query, result);
void get(String resource, String query, String result)
String resource  String query  String result
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
message(Message.SYNC, resource, "POST", query, result);
void post(String resource, String query, String result)
String resource  String query  String result
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
message(Message.SYNC, resource, "PUT", query, result);
void put(String resource, String query, String result)
String resource  String query  String result
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
message(Message.DESTROY, resource, "DELETE", query, result);
void delete(String resource, String query, String result)
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
return layout.layout(root);
String toString()
int type  String resourceTo  String method  String args  String result
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
Agent agentTo = agentFor(resourceTo);
        String methodSignature = args == null ? method : method + "(" + args + ")";
        String resultString = result == null ? "" : result;
        Message message = new Message(type, agentTo, methodSignature, resultString);
        root.add(new Node(message));
void message(int type, String resourceTo, String method, String args, String result)
String resource
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
Resource a = resourceToAgentMap.get(resource);
        if (a == null) {
            boolean isActivable = true;
            a = new Resource(resource, isActivable);
            resourceToAgentMap.put(resource, a);
        return a;
Resource agentFor(String resource)
String type  boolean isActivable
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
super(type, "", isActivable);
public Resource(String type, boolean isActivable)
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
return isEllipsis() ? "..." : (new StringBuilder()).append(getType()).toString();
    private final Model model;
    private final String picFileName;
    private final Map<String, String> attributes;
     *            diagram is not known until the fixture has been created @
    public MyFixtureListener(String outFileName, Model m, Map<String, String> attr) {
        model = m;
        attributes = attr != null ? attr : new HashMap<String, String>();
        picFileName = outFileName;
        int pos = picFileName.lastIndexOf(".");
        String format = "svg";
        if (pos > 0) {
            format = picFileName.substring(pos + 1).toLowerCase();
String toString()
src/main/java/smartrics/rest/fitnesse/fixture/SlimRow.java
if (row != null) {
            return row.size();
int size()
src/test/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeqFitTest.java
RowWrapper<?> row = helper.createTestRow("embed", "");
        fixture.processRow(row);
        verify(row.getCell(1)).body();
        verify(row.getCell(1)).body(
                "<img src=\"data:image/svg;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjE"
                        + "iPg0KICA8ZGVmcz4NCiAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KICAgICAgPCFbQ0RBVEFbDQogICAgICAgIHJlY3QuY2xhc"
                        + "3Nib3h7DQogICAgICAgICAgc3Ryb2tlICAgICAgIDogYmxhY2s7DQogICAgICAgICAgc3Ryb2tlLXdpZHRoIDogMTsNCiAgICAgICA"
                        + "gICBmaWxsCQkgICA6IHdoaXRlOw0KICAgICAgICB9DQogICAgICAgIGVsbGlwc2UucGF0dGVybnsNCiAgICAgICAgICBzdHJva2UgI"
                        + "CAgICAgOiBibGFjazsNCiAgICAgICAgICBzdHJva2Utd2lkdGggOiAxOw0KICAgICAgICAgIGZpbGwJCSAgIDogd2hpdGU7DQogICA"
                        + "gICAgICAgc3Ryb2tlLWRhc2hhcnJheTogOSw1Ow0KICAgICAgICB9DQogICAgICAgIGxpbmUuY2xhc3Nib3h7DQogICAgICAgICAgc"
                        + "3Ryb2tlICAgICAgIDogYmxhY2s7DQogICAgICAgICAgc3Ryb2tlLXdpZHRoIDogMTsNCiAgICAgICAgfQ0KICAgICAgICBwb2x5Z29"
                        + "uLmNsYXNzYm94ew0KICAgICAgICAgIGZpbGwJCSAgIDogd2hpdGU7DQogICAgICAgICAgc3Ryb2tlICAgICAgIDogd2hpdGU7DQogI"
                        + "CAgICAgICAgc3Ryb2tlLXdpZHRoIDogMDsNCiAgICAgICAgfQ0KICAgICAgICBwb2x5Z29uLm5vdGV7DQogICAgICAgICAgZmlsbAk"
                        + "JICAgOiB3aGl0ZTsNCiAgICAgICAgICBzdHJva2UgICAgICAgOiBibGFjazsNCiAgICAgICAgICBzdHJva2Utd2lkdGggOiAxOw0KI"
                        + "CAgICAgICB9DQogICAgICAgIGxpbmUubGlmZWxpbmV7DQogICAgICAgICAgc3Ryb2tlICAgICAgIDogYmxhY2s7DQogICAgICAgICA"
                        + "gc3Ryb2tlLXdpZHRoIDogMTsNCiAgICAgICAgICBzdHJva2UtZGFzaGFycmF5OiA5LDU7DQogICAgICAgIH0NCiAgICAgICAgcGF0a"
                        + "C5hcnJvd3sNCiAgICAgICAgICBmaWxsCQkgICA6IG5vbmU7DQogICAgICAgICAgc3Ryb2tlICAgICAgIDogYmxhY2s7DQogICAgICA"
                        + "gICAgc3Ryb2tlLXdpZHRoIDogMTsNCiAgICAgICAgfQ0KICAgICAgICBwYXRoLmRhc2hhcnJvd3sNCiAgICAgICAgICBmaWxsCQkgI"
                        + "CA6IG5vbmU7DQogICAgICAgICAgc3Ryb2tlICAgICAgIDogYmxhY2s7DQogICAgICAgICAgc3Ryb2tlLXdpZHRoIDogMTsNCiAgICA"
                        + "gICAgICBzdHJva2UtZGFzaGFycmF5OiAxMCw3Ow0KICAgICAgICB9DQogICAgICAgIHRleHR7DQogICAgICAgICAgZmlsbCAgICAgI"
                        + "CAgIDogYmxhY2s7DQogICAgICAgICAgc3Ryb2tlLXdpZHRoIDogMDsNCiAgICAgICAgICBmb250LWZhbWlseSAgOiBzYW5zLXNlcml"
                        + "mOw0KICAgICAgICB9DQogICAgICAgIHRleHQubmFtZXsNCiAgICAgICAgICBmb250LXNpemUgICAgOiAxMnB4Ow0KICAgICAgICAgI"
                        + "GZvbnQtd2VpZ2h0ICA6IGJvbGQ7DQogICAgICAgICAgdGV4dC1hbmNob3IgIDogbWlkZGxlOw0KICAgICAgICB9DQogICAgICAgIHR"
                        + "leHQuaXRlbXsNCiAgICAgICAgICBmb250LXNpemUgICAgOiAxMnB4Ow0KICAgICAgICB9DQogICAgICAgIHRleHQudmlzaWJpbGl0e"
                        + "XsNCiAgICAgICAgICBmb250LXNpemUgICAgOiAxMnB4Ow0KICAgICAgICAgIGZvbnQtZmFtaWx5ICA6IG1vbm9zcGFjZTsNCiAgICA"
                        + "gICAgICBmb250LXdlaWdodCAgOiBib2xkOw0KICAgICAgICAgIHRleHQtYW5jaG9yICA6IG1pZGRsZTsNCiAgICAgICAgfQ0KICAgI"
                        + "CAgICB0ZXh0LmFic3RyYWN0ew0KICAgICAgICAgIGZvbnQtc3R5bGUgICA6IGl0YWxpYzsNCiAgICAgICAgfQ0KICAgICAgICB0ZXh"
                        + "0Lm1lc3NhZ2V7DQogICAgICAgICAgZm9udC1zaXplICAgIDogMTJweDsNCiAgICAgICAgICB0ZXh0LWFuY2hvciAgOiBzdGFydDsNC"
                        + "iAgICAgICAgfQ0KICAgICAgICB0ZXh0LmJhY2ttZXNzYWdlew0KICAgICAgICAgIGZvbnQtc2l6ZSAgICA6IDEycHg7DQogICAgICA"
                        + "gICAgdGV4dC1hbmNob3IgIDogZW5kOw0KICAgICAgICB9DQogICAgICBdXT4NCiAgICA8L3N0eWxlPg0KICANCiAgDQogICAgPG1hc"
                        + "mtlciBpZD0ibm9IZWFkIiByZWZYPSIwIiByZWZZPSIwIiA+PC9tYXJrZXI+DQogIA0KICAgIDwhLS0gVU1MIFNlcXVlbmNlIFN5bmM"
                        + "gTWVzc2FnZSBIZWFkIC0tPg0KICAgIDxtYXJrZXIgaWQ9ImNsb3NlZEhlYWQiDQogICAgICB2aWV3Qm94PSIwIDAgMzAgMzAiIHJlZ"
                        + "lg9IjMwIiByZWZZPSIxNSIgDQogICAgICBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiDQogICAgICBtYXJrZXJXaWR0aD0iMTAiIG1"
                        + "hcmtlckhlaWdodD0iMTAiDQogICAgICBvcmllbnQ9ImF1dG8iPg0KICAgICAgPHBhdGggZD0iTSAwIDAgTCAzMCAxNSBMIDAgMzAge"
                        + "iIgLz4NCiAgICA8L21hcmtlcj4NCiAgICANCiAgICA8IS0tIFVNTCBTZXF1ZW5jZSBBc3luYyBNZXNzYWdlIEhlYWQgLS0+DQogICA"
                        + "gPG1hcmtlciBpZD0iaGFsZkNsb3NlZEhlYWQiDQogICAgICB2aWV3Qm94PSIwIDAgMzAgMzAiIHJlZlg9IjMwIiByZWZZPSIxNSIgD"
                        + "QogICAgICBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiDQogICAgICBtYXJrZXJXaWR0aD0iMTUiIG1hcmtlckhlaWdodD0iMTUiDQo"
                        + "gICAgICBvcmllbnQ9ImF1dG8iPg0KICAgICAgPHBhdGggZD0iTSAwIDE1IDMwIDE1IEwgMCAzMCB6IiAvPg0KICAgIDwvbWFya2VyP"
                        + "g0KICAgIA0KICAgIDwhLS0gVU1MIEluaGVyaXRhbmNlIEhlYWQgLS0+DQogICAgPG1hcmtlciBpZD0iZW1wdHlIZWFkIg0KICAgICA"
                        + "gdmlld0JveD0iMCAwIDMwIDMwIiByZWZYPSIzMCIgcmVmWT0iMTUiIA0KICAgICAgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIg0KI"
                        + "CAgICAgbWFya2VyV2lkdGg9IjE1IiBtYXJrZXJIZWlnaHQ9IjE1Ig0KICAgICAgb3JpZW50PSJhdXRvIj4NCiAgICAgIDxwYXRoIGQ9"
                        + "Ik0gMCAwIEwgMzAgMTUgTCAwIDMwIHoiIGZpbGw9IndoaXRlIiBzdHJva2U9ImJsYWNrIiAvPg0KICAgIDwvbWFya2VyPg0KICAgI"
                        + "A0KICAgIDwhLS0gVU1MIEFzc29jaWF0aW9uIEhlYWQgLS0+DQogICAgPG1hcmtlciBpZD0ib3BlbkhlYWQiDQogICAgICB2aWV3Qm94P"
                        + "SIwIDAgMzAgMzAiIHJlZlg9IjMwIiByZWZZPSIxNSIgDQogICAgICBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiDQogICAgICBtYX"
                        + "JrZXJXaWR0aD0iMTAiIG1hcmtlckhlaWdodD0iMTAiDQogICAgICBvcmllbnQ9ImF1dG8iPg0KICAgICAgPHBhdGggZD0iTSAwIDA"
                        + "gTCAzMCAxNSBMIDAgMzAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIC8+DQogICAgPC9tYXJrZXI+DQogICAgDQogICAgPCEt"
                        + "LSBIZWFkIC0tPg0KICAgIDxtYXJrZXIgaWQ9ImhhbGZPcGVuSGVhZCINCiAgICAgIHZpZXdCb3g9IjAgMCAzMCAzMCIgcmVmWD0iMz"
                        + "AiIHJlZlk9IjE1IiANCiAgICAgIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCINCiAgICAgIG1hcmtlcldpZHRoPSIxNSIgbWFya2Vy"
                        + "SGVpZ2h0PSIxNSINCiAgICAgIG9yaWVudD0iYXV0byI+DQogICAgICA8cGF0aCBkPSJNIDAgMTUgTCAzMCAxNSBMIDAgMzAiIGZpbG"
                        + "w9Im5vbmUiIHN0cm9rZT0iYmxhY2siIC8+DQogICAgPC9tYXJrZXI+DQogICAgDQogICAgPCEtLSBVTUwgQWdncmVnYXRpb24gVGFp"
                        + "bCAtLT4NCiAgICA8bWFya2VyIGlkPSJvcGVuRGlhbW9uZCINCiAgICAgIHZpZXdCb3g9IjAgMCAzMCAzMCIgcmVmWD0iMCIgcmVmWT"
                        + "0iMTUiIA0KICAgICAgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIg0KICAgICAgbWFya2VyV2lkdGg9IjE1IiBtYXJrZXJIZWlnaHQ9"
                        + "IjE1Ig0KICAgICAgb3JpZW50PSJhdXRvIj4NCiAgICAgIDxwYXRoIGQ9Ik0gMCAxNSBMIDE1IDMgTCAzMCAxNSBMIDE1IDI3IHoiIG"
                        + "ZpbGw9IndoaXRlIiBzdHJva2U9ImJsYWNrIiAvPg0KICAgIDwvbWFya2VyPg0KICAgIA0KICAgIDwhLS0gVU1MIENvbXBvc2l0aW9u"
                        + "IFRhaWwgLS0+DQogICAgPG1hcmtlciBpZD0iY2xvc2VkRGlhbW9uZCINCiAgICAgIHZpZXdCb3g9IjAgMCAzMCAzMCIgcmVmWD0iMC"
                        + "IgcmVmWT0iMTUiIA0KICAgICAgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIg0KICAgICAgbWFya2VyV2lkdGg9IjE1IiBtYXJrZXJI"
                        + "ZWlnaHQ9IjE1Ig0KICAgICAgb3JpZW50PSJhdXRvIj4NCiAgICAgIDxwYXRoIGQ9Ik0gMCAxNSBMIDE1IDMgTCAzMCAxNSBMIDE1ID"
                        + "I3IHoiIC8+DQogICAgPC9tYXJrZXI+DQogICAgDQogICAgPCEtLSBVTUwgQ29tcG9uZW50IEludGVyZmFjZSBQcm92aWRlZCBIZWFk"
                        + "IC0tPg0KICAgIDxtYXJrZXIgaWQ9ImVtcHR5Q2lyY2xlIg0KICAgICAgdmlld0JveD0iMCAwIDMwIDMwIiByZWZYPSIxNSIgcmVmWT"
                        + "0iMTUiIA0KICAgICAgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIg0KICAgICAgbWFya2VyV2lkdGg9IjE1IiBtYXJrZXJIZWlnaHQ9"
                        + "IjE1IiA+DQogICAgIDxjaXJjbGUgY3g9IjE1IiBjeT0iMTUiIHI9IjEwIiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2"
                        + "tlLXdpZHRoPSIxIiAvPg0KICAgIDwvbWFya2VyPg0KICAgIA0KICAgIDwhLS0gVU1MIENvbXBvbmVudCBJbnRlcmZhY2UgUmVxdWly"
                        + "ZWQgVGFpbCAtLT4NCiAgICA8bWFya2VyIGlkPSJoYWxmQXJjIg0KICAgICAgdmlld0JveD0iMCAwIDMwIDMwIiByZWZYPSIxNSIgcm"
                        + "VmWT0iMTUiIA0KICAgICAgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIg0KICAgICAgbWFya2VyV2lkdGg9IjE1IiBtYXJrZXJIZWln"
                        + "aHQ9IjE1Ig0KICAgICAgb3JpZW50PSJhdXRvIj4NCiAgICAgPHBhdGggZD0iTSAxNSwwIGExMiwxMiAwIDAsMCAxNSwzMCIgZmlsbD"
                        + "0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxIiAvPg0KICAgIDwvbWFya2VyPg0KICAgIA0KICAgIDxkZXNjPkNv"
                        + "bXBvbmVudCBTeW1ib2w8L2Rlc2M+DQogICAgPHN5bWJvbCBpZD0iQ29tcG9uZW50IiB2aWV3Qm94PSIwIDAgMTYgMjUiID4NCiAgIC"
                        + "AgIDxyZWN0IHg9IjQiIHk9IjAiIHdpZHRoPSIxMiIgaGVpZ2h0PSIyMCIgZmlsbD0id2hpdGUiIHN0cm9rZT0iYmxhY2siIC8+DQog"
                        + "ICAgICA8cmVjdCB4PSIwIiB5PSI0IiB3aWR0aD0iOCIgaGVpZ2h0PSI1IiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIgLz4NCi"
                        + "AgICAgIDxyZWN0IHg9IjAiIHk9IjEyIiB3aWR0aD0iOCIgaGVpZ2h0PSI1IiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIvPg0K"
                        + "ICAgIDwvc3ltYm9sPg0KICAgIA0KICAgIDxkZXNjPkhpZXJhcmNoeSBTeW1ib2w8L2Rlc2M+DQogICAgPHN5bWJvbCBpZD0iSGllcm"
                        + "FyY2h5IiB2aWV3Qm94PSIwIDAgMTYgMjUiID4NCiAgICAgIDxyZWN0IHg9IjUiIHk9IjAiIHdpZHRoPSI2IiBoZWlnaHQ9IjYiIGZp"
                        + "bGw9IndoaXRlIiBzdHJva2U9ImJsYWNrIiAvPg0KICAgICAgPHJlY3QgeD0iMCIgeT0iMTIiIHdpZHRoPSI2IiBoZWlnaHQ9IjYiIG"
                        + "ZpbGw9IndoaXRlIiBzdHJva2U9ImJsYWNrIi8+DQogICAgICA8cmVjdCB4PSIxMCIgeT0iMTIiIHdpZHRoPSI2IiBoZWlnaHQ9IjYi"
                        + "IGZpbGw9IndoaXRlIiBzdHJva2U9ImJsYWNrIi8+DQogICAgICA8cGF0aCBkPSJNIDMsMTEgTCAzLDkgTCAxMyw5IEwgMTMsMTEiIG"
                        + "ZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMSIgLz4NCiAgICAgIDxsaW5lIHgxPSI4IiB4Mj0iOCIgeTE9"
                        + "IjkiIHkyPSI3IiBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjEiIC8+DQogICAgPC9zeW1ib2w+DQogIC"
                        + "AgDQogICAgPGRlc2M+RGVsZWdhdGlvbiBTeW1ib2w8L2Rlc2M+DQogICAgPHN5bWJvbCBpZD0iRGVsZWdhdGlvbiIgdmlld0JveD0i"
                        + "MCAwIDE2IDI1IiA+DQogICAgICA8cmVjdCB4PSIwIiB5PSI1IiB3aWR0aD0iNiIgaGVpZ2h0PSI2IiBmaWxsPSJ3aGl0ZSIgc3Ryb2"
                        + "tlPSJibGFjayIvPg0KICAgICAgPHJlY3QgeD0iMTAiIHk9IjUiIHdpZHRoPSI2IiBoZWlnaHQ9IjYiIGZpbGw9IndoaXRlIiBzdHJv"
                        + "a2U9ImJsYWNrIi8+DQogICAgICA8bGluZSB4MT0iNiIgeDI9IjEwIiB5MT0iOCIgeTI9IjgiIGZpbGw9Im5vbmUiIHN0cm9rZT0iYm"
                        + "xhY2siIHN0cm9rZS13aWR0aD0iMSIgLz4NCiAgICA8L3N5bWJvbD4NCiAgICANCiAgICA8ZGVzYz5SYWRpYWwgU3ltYm9sPC9kZXNj"
                        + "Pg0KICAgIDxzeW1ib2wgaWQ9IlJhZGlhbCIgdmlld0JveD0iMCAwIDE2IDI1IiA+DQogICAgICA8cmVjdCB4PSI2IiB5PSIwIiB3aW"
                        + "R0aD0iNSIgaGVpZ2h0PSI1IiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIvPg0KICAgICAgPHJlY3QgeD0iMCIgeT0iNiIgd2lk"
                        + "dGg9IjUiIGhlaWdodD0iNSIgZmlsbD0id2hpdGUiIHN0cm9rZT0iYmxhY2siLz4NCiAgICAgIDxyZWN0IHg9IjEyIiB5PSI2IiB3aW"
                        + "R0aD0iNSIgaGVpZ2h0PSI1IiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIvPg0KICAgICAgPHJlY3QgeD0iNiIgeT0iMTQiIHdp"
                        + "ZHRoPSI1IiBoZWlnaHQ9IjUiIGZpbGw9IndoaXRlIiBzdHJva2U9ImJsYWNrIi8+DQogICAgICA8bGluZSB4MT0iOCIgeTE9IjE0Ii"
                        + "B4Mj0iOCIgeTI9IjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMSIgLz4NCiAgICAgIDxsaW5lIHgx"
                        + "PSI4IiB5MT0iMTQiIHgyPSIzIiB5Mj0iMTEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMSIgLz4NCi"
                        + "AgICAgIDxsaW5lIHgxPSI4IiB5MT0iMTQiIHgyPSIxMiIgeTI9IjExIiBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBzdHJva2Ut"
                        + "d2lkdGg9IjEiIC8+DQogICAgPC9zeW1ib2w+DQogICAgDQogICAgPGRlc2M+RmxvdyBTeW1ib2w8L2Rlc2M+DQogICAgPHN5bWJvbC"
                        + "BpZD0iRmxvdyIgdmlld0JveD0iMCAwIDE2IDI1IiA+DQogICAgICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iNSIgaGVpZ2h0PSI1"
                        + "IiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJibGFjayIvPg0KICAgICAgPHJlY3QgeD0iOSIgeT0iMCIgd2lkdGg9IjUiIGhlaWdodD0iNS"
                        + "IgZmlsbD0id2hpdGUiIHN0cm9rZT0iYmxhY2siLz4NCiAgICAgIDxyZWN0IHg9IjAiIHk9IjgiIHdpZHRoPSI1IiBoZWlnaHQ9IjUi"
                        + "IGZpbGw9IndoaXRlIiBzdHJva2U9ImJsYWNrIi8+DQogICAgPC9zeW1ib2w+DQogICAgDQogIDwvZGVmcz4NCiAgDQoKPGRlc2M+QW"
                        + "dlbnRzIGFuZCBsaWZlbGluZXMgb2YgdGhlIHNlcXVlbmNlIGRpYWdyYW08L2Rlc2M+Cgo8ZGVzYz5NZXNzYWdlczwvZGVzYz4NCiAgDQo8L3N2Zz4NCg==\" />");
        verifyNoMoreInteractions(row.getCell(1));
        verifyNoMoreInteractions(mockModel);
void shouldEmbedAPictureWithAnImgTagAndAnEncodedInlineImg()
src/test/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeqFitTest.java
lastResponse.addHeader("Location", "/resources/999");
        RowWrapper<?> row = helper.createTestRow("POST", "/uri", "", "", "");
        fixture.setModel(mockModel);
        verify(mockModel).post("/uri", null, "id=999, status=200");
        verifyNoMoreInteractions(mockModel);
    public void mustDelegateToModelAComment() {
        RowWrapper<?> row = helper.createTestRow("comment", "some text");
        fixture.setModel(mockModel);
        verify(mockModel).comment("some text");
        verifyNoMoreInteractions(mockModel);
    public void mustDelegateToModelAGet() {
        RowWrapper<?> row = helper.createTestRow("GET", "/uri/123", "", "", "");
        fixture.setModel(mockModel);
        verify(mockModel).get("/uri/123", null, "status=200");
        verifyNoMoreInteractions(mockModel);
    public void mustDelegateToModelAPut() {
        RowWrapper<?> row = helper.createTestRow("PUT", "/uri/123", "", "", "");
        fixture.setModel(mockModel);
        verify(mockModel).put("/uri/123", null, "status=200");
        verifyNoMoreInteractions(mockModel);
void mustDelegateToModelAPost()
String hostName  String pictureName
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
this.pictureName = pictureName;
    public RestFixtureWithSeq(String hostName, String configName, String pictureName) {
        this.pictureName = pictureName;
    public RestFixtureWithSeq(PartsFactory partsFactory, String hostName, String configName, String pictureName) {
        this.pictureName = pictureName;
        create(new PicDiagram(), new Model());
        if(!graphFileDir.exists()) {
            if(!graphFileDir.mkdirs()) {
        String supportDirName = getConfig().get("restfixture.graphs.support.files.dir", DEFAULT_SUPPORT_FILES_DIR_NAME);
        File supportDir = validateSupportDirContent(supportDirName);

        setFixtureListener(new MyFixtureListener(this, builder, supportDir, graphFileDir));
    protected String getPictureNameFromArgs() {
        return getBaseUrl() != null && getPictureName() != null;
            throw new FitFailureException("Both baseUrl and picture name need to be passed to the fixture");
    void create(PicDiagram d, Model m) {
        diagram = d;
        model = m;
        builder = new Builder(model, diagram);
        // return super.doTable(rows);
        throw new RuntimeException("This fixture is not supported on SLIM runner. Please use it with FIT");
        this.pictureName = getPictureNameFromArgs();
        model.addEvent(new Message(FIXTURE, getLastRequest().getResource(), "DELETE"));
        model.addEvent(new Return(getLastRequest().getResource(), FIXTURE, getLastResponse().getStatusCode().toString()));
        model.addEvent(new Message(FIXTURE, getLastRequest().getResource(), "GET", getLastRequest().getQuery()));
        model.addEvent(new Return(getLastRequest().getResource(), FIXTURE, getLastResponse().getStatusCode().toString()));
        String res = getLastRequest().getResource();
        Event event = new Message(FIXTURE, res, "POST");
        model.addEvent(event);
        List<Header> list = getLastResponse().getHeader("Location");
        String location = "";
        if (list != null && !list.isEmpty()) {
            location = list.get(0).getValue();
public RestFixtureWithSeq(String hostName, String pictureName)
Model m
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
this.model = m;
    Model getModel() {
        return this.model;
    void setFixtureListener(FixtureListener l) {
        super.listener = l;
    private File validateSupportDirContent(String supportDirName) {
        File supportDir = new File(supportDirName);
        if (!supportDir.exists()) {
            throw new FitFailureException("Support files directory is missing '" + supportDir.getAbsolutePath() + "'");
        File sequence_pic = new File(supportDir, "sequence.pic");
        if (!sequence_pic.exists()) {
            throw new FitFailureException("Missing support file '" + sequence_pic.getAbsolutePath() + "'");
        File myPs2Img_sh = new File(supportDir, "myps2img.sh");
        if (!myPs2Img_sh.exists()) {
            throw new FitFailureException("Missing support file '" + myPs2Img_sh.getAbsolutePath() + "'");
        return supportDir;
    private final Builder sequenceBuilder;
    private final RestFixtureWithSeq thisFixture;
    private final GraphGenerator graphGenerator;
    private final File graphDirectory;
     *            diagram is not known until the fixture has been created
     * @param b
     *            the sequence diagram builder
    public MyFixtureListener(RestFixtureWithSeq f, Builder b, File supportFilesDir, File graphDir) {
        sequenceBuilder = b;
        thisFixture = f;
        graphDirectory = graphDir;
        graphGenerator = new GraphGenerator(supportFilesDir.getAbsolutePath());
        sequenceBuilder.build();
        String diag = sequenceBuilder.getDiagram().toString();
            File graphFile = new File(graphDirectory, thisFixture.getPictureName());
            init(graphFile);
            System.out.println("Generating sequence diagram in " + graphFile.getAbsolutePath());
            graphGenerator.generateGif(diag, graphFile);
void setModel(Model m)
File graphFile
src/main/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeq.java
if (!graphDirectory.exists()) {
            try {
                graphDirectory.mkdirs();
void init(File graphFile)
src/test/java/smartrics/rest/fitnesse/fixture/RestFixtureWithSeqFitTest.java
RowWrapper<?> row = helper.createTestRow("PUT", "/uri", "", "", "");
        assertOnMethods("PUT");
    public void mustGenerateTwoEventsForGet() {
        RowWrapper<?> row = helper.createTestRow("GET", "/uri", "", "", "");
        assertOnMethods("GET");
    public void mustGenerateTwoEventsForDelete() {
        RowWrapper<?> row = helper.createTestRow("DELETE", "/uri", "", "", "");
        assertOnMethods("DELETE");
    public void mustGenerateThreeEventsForPost() {
        lastResponse.addHeader("Location", "/resources/999");
        RowWrapper<?> row = helper.createTestRow("POST", "/uri", "", "", "");
        assertEquals(3, fixture.getModel().getEvents().size());
        Event event = fixture.getModel().getEvents().get(0);
        assertTrue(event instanceof Message);
        assertEquals("POST", event.getName());
        assertTrue(fixture.getModel().getEvents().get(1) instanceof Create);
        assertTrue(fixture.getModel().getEvents().get(2) instanceof Return);
    private void assertOnMethods(String name) {
        assertEquals(2, fixture.getModel().getEvents().size());
        Event event = fixture.getModel().getEvents().get(0);
        assertTrue(event instanceof Message);
        assertTrue(fixture.getModel().getEvents().get(1) instanceof Return);
        assertEquals(name, event.getName());
void mustGenerateTwoEventsForPut()