this is fixed in the latest version.

If you have a method on a fixture that returns a value and changes the state of the fixture, or application, you may see some odd result: like a failed cell that shows that actual and expected are the same.

here is info and a fix provided by Mark W. I am not sure if there are related problems remaining.

I have been evaluating the FitLib[?] and Fitnesse (VC++ 6, from the 20050126 zip). As part of my evaluation, I created the 'eg.Division' example from Fitnesse. Once I got that working, I wanted to know how many times the eg.Division interface was instantiated and how many times the test methods were called. I added another test 'half', and also added static counters for construction and for when 'quotient' or 'half' were called.

Here are the results from the run as cut from the result page from Fitnesse. If you cannot readily see the html table, the errored responses for quotient were displaying quot_counts greater than expected.

eg.Division
numerator denominator quotient? half? inst_counts? quot_counts? half_counts?
10 2 5 2.5 1 1 1
12.6 3 4.2 2.1 1 2 2
100 4 25.0 expected
25 actual
12.5 1 3 expected
4 actual
3
12.5 0 error expected
1.#INF actual
1.#INF 1 4 expected
6 actual
4



Here are the results after my corrections:


eg.Division
numerator denominator quotient? half? inst_counts? quot_counts? half_counts?
10 2 5 2.5 1 1 1
12.6 3 4.2 2.1 1 2 2
100 4 25.0 expected
25 actual
12.5 1 3 3
12.5 0 error expected
1.#INF actual
1.#INF 1 4 4


I'm not sure if my work-around is the sufficient, but the code I changed is in Fixture::check() -- it appeared to me that the adapter invoke() was being called twice on 'error' or on a miscompare, either through invoke() and through valueAsString() or from two valueAsString() calls.

I've included my code changes below, where the old code is #if'ed out.

I really dont have enough context to know if this was an appropriate solution, nor do I have a good set of

Best-regards,
Mark Winrock




void Fixture::check(ParsePtr cell, TypeAdapter *a) 
{
    if (a == 0) {
        ignore(cell);
        return;
    }

    string text = cell->text();
    if (text == "") {
        return;
    }
    if (text == "error") {
        try {
#if 0        
            a->invoke();
#else
            // mawFindMe: I removed the invoke() because
            // valueAsString() calls invoke().
#endif
            wrong(cell, a->valueAsString());
        } catch (ResolutionException& e) {
            handleException (cell, e);
        } catch (exception&) {
            right(cell);
        }
        return;
    }
    try {

#if 0    
        if (a->valueAsString() == text) {
            right(cell);
        } else {
            wrong(cell, a->valueAsString());
        }        

#else
        // mawFindMe: I changed this to only call valueAsString() once
        string v = a->valueAsString();
        if (v == text) {
            right(cell);
        } else {
            wrong(cell, v);
        }
#endif
    } catch (exception& e) {
        handleException(cell, e);
    }
}