import CursoredList;
import SimpleOutput;
import Comparator;

/**
 * A simple test of cursored lists.  Usage:
 *   CLTester tester = new CLTester(sample-list);
 *   tester.test();
 *
 * @author Samuel A. Rebelsky
 * @version 1.0 of November 1999
 */
public class CLTester {
  /** The list we're testing. */
  CursoredList list;
  /** For output. */
  SimpleOutput out;
  /** For comparisons. */
  Comparator compare;
  
  /**
   * Set up a tester for a pacticular initially-empty list.
   */
  public CLTester(CursoredList testme) {
    this.list = testme;
    this.out = new SimpleOutput();
    this.compare = new StringComparator();
  } // CLTester(CursoredList)

  /**
   * Given an initially empty list, try various operations.
   * Note that the toString method tests advance, getCurrent,
   * and front
   */
  public void test() {
    // Some tests adding at the front and back of the list.
    this.out.print("Adding A to the front of the list ... ");
    this.list.addToFront("A");
    check("(A )", toString(this.list));
    
    this.out.print("Adding B to the end of the list ... ");
    this.list.addToEnd("B");
    check("(A B )", toString(this.list));

    this.out.print("Adding Z to the front of the list ... ");
    this.list.addToFront("Z");
    check("(Z A B )", toString(this.list));
   
    // Some tests adding in the middle of the list.  Note that
    // the position of the cursor is unspecified after addition.

    this.out.print("Adding D after Z ... ");
    this.list.front();
    this.list.addAfterCursor("D");
    check("(Z D A B )", toString(this.list));
    // this.out.println("  The current element is '" 
    //   + this.list.getCurrent() + "'");

    this.out.print("Adding E after D ... ");
    this.list.front();			// On the Z
    try { this.list.advance(); }	// On to the D
    catch (Exception E) {
      this.out.print("Couldn't advance ... ");
    }
    this.list.addAfterCursor("E");
    check("(Z D E A B )", toString(this.list));

    // Some tests finding.

    this.out.print("Finding A using the self-compare method ... ");
    this.list.front();
    try { this.list.find("A"); }
    catch (Exception e) { out.print("ran off the list ... "); }
    check("A", this.list.getCurrent().toString());

    this.out.print("Finding the next A ... ");
    try {
      this.list.find("A");
      this.out.println("FAILED\n  Found a second A");
    }
    catch (Exception E) {
      this.out.println("OK (not found)");
    }

    this.out.print("Finding the first A using a stringcomparator ... ");
    this.list.front();
    try { this.list.find("a", compare); }
    catch (Exception e) { out.print("ran off the list ... "); }
    check("A", this.list.getCurrent().toString());

    // Some tests deleting.

    this.out.print("Deleting last element using find ... ");
    this.list.front();
    try { this.list.find("B"); }
    catch (Exception e) { out.print("ran off the list ... "); }
    this.list.delete();
    check("(Z D E A )", toString(this.list));

    this.out.print("Deleting first element ... ");
    this.list.front();
    this.list.delete();
    check("(D E A )", toString(this.list));

    this.out.print("Deleting E ... ");
    this.list.front();
    try { this.list.find("E"); }
    catch (Exception e) { out.print("ran off the list ... "); }
    this.list.delete();
    check("(D A )", toString(this.list));

    // What's happened to our list? 

    this.out.print("Finding now-deleted E ... ");
    this.list.front();
    try {
      this.list.find("E");
      this.out.println("FAILED");
    }
    catch (Exception e) {
      this.out.println("OK");
    }

    this.out.print("Adding X after D ... ");
    this.list.front();
    this.list.addAfterCursor("X");
    check("(D X A )", toString(this.list));
  } // test(CursoredList)

  /**
   * Check whether expected output meets actual output.
   */
  public void check(String expected, String actual) {
    if (expected.equals(actual)) {
      this.out.println("OK");
    } 
    else {
      this.out.println("FAILED");
      this.out.println("  Expected: " + expected);
      this.out.println("  Got: " + actual);
    }
  } // check(String,String)

  /**
   * Turn a cursored list into a string.
   */
  public String toString(CursoredList cl) {
    String result = "(";
    cl.front();
    try {
      // Keep printing the current element and then advancing the
      // cursor until you advance off the end of the list.  At that
      // point, the advance method should throw an exception and 
      // we escape from the while loop.
      while (true) {
        result = result + cl.getCurrent() + " ";
        cl.advance();
      }
    }
    catch (Exception e) {
    }
    result = result + ")";
    return result;
  } // toString(CursoredList)
} // CLTester

