import junit.framework.TestCase;

import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;

/*
 * 
 new String("") used to catch =="".
 
 
 ArrayList<Integer> used to catch assumptions about List<E>, after grepping revealed
 no reliance on ArrayList, Integer (but: autoboxing?)
 
 Haven't delved into full subtleties of autoboxing: new Integer(i) with i >= 127
 believe guaranteed not to intern so it tests equals, but may be overkill.
 
 Doesn't catch list mutation: too small likelihood/effort ratio, should also be caught
 by TA verifying variable rule.
 
 
 Contains:
 
 Groups four tests otherwise trivial wrong code produces 25% or 75% correct.
 
 Not testing for reaction to null elements: slightly beyond scope of exercise.
 
 
 Copying:
 
 Should return a copy, not original.
 Not testing that "" is a true copy (i.e. non-interned): very special behaviour of Strings.
 For non-empty String check !=.
 For List: ArrayList to LinkedList guarantees !=.
 
 Shouldn't copy elements.
 Grepped for clone() instead, which is the only real possibility. 
 
 */

public class Ex5TestCase extends TestCase {
  
  public void testStringLengthEmpty() {
    assertEquals(0, E.length(new String("")));
  }
  public void testStringLengthTypical() {
    assertEquals(4, E.length("abcd"));
  }
  
  public void testListLengthEmpty() {
    assertEquals(0, E.length(new ArrayList<Integer>()));
  }
  public void testListLengthTypical() {
    List<Integer> list = new ArrayList<Integer>();
    for (int i=0; i<5; i++) {
      list.add(0);
    }
    assertEquals(5, E.length(list));
  }
  
  public void testStringContainsEmpty() {
    assertFalse(E.contains(new String(""), 'a'));
  }
  public void testStringContainsTypical() {
    assertTrue(E.contains("abc", 'a'));
    assertTrue(E.contains("abc", 'b'));
    assertTrue(E.contains("abc", 'c'));
    assertFalse(E.contains("abc", 'd'));
  }
  
  public void testListContainsEmpty() {
    assertFalse(E.contains(new ArrayList<Integer>(), 5));
  }
  public void testListContainsTypical() {
    List<Integer> list = new ArrayList<Integer>();
    for (int i=0; i<5; i++) {
      list.add(new Integer(128 + i));
    }
    assertTrue(E.contains(list, new Integer(128 + 0)));
    assertTrue(E.contains(list, new Integer(128 + 2)));
    assertTrue(E.contains(list, new Integer(128 + 4)));
    assertFalse(E.contains(list, new Integer(128 + 5)));
  }
  
  public void testStringCopyEmpty() {
    assertEquals("", E.copy(new String("")));
  }
  public void testStringCopyTypical() {
    String copy = E.copy("ABC");
    assertEquals("ABC", copy);
    assertFalse("ABC"==copy);
  }
  
  public void testListCopyEmpty() {
    assertEquals(new LinkedList<Integer>(), E.copy(new ArrayList<Integer>()));
  }
  public void testListCopyTypical() {
    List<Integer> list = new ArrayList<Integer>();
    for (int i=0; i<5; i++) {
      list.add(new Integer(128 + i));
    }
    List<Integer> result = E.copy(list);
    assertEquals(5, result.size());
    for (int i=0; i<5; i++) {
      assertEquals(list.get(i), result.get(i));
    }
  }
  
  
  public void testStringReverseEmpty() {
    assertEquals("", E.reverseCopy(new String("")));
  }
  public void testStringReverseTypical() {
    String rc = E.reverseCopy("ABC");
    assertEquals("CBA", rc);
  }
  
  public void testListReverseEmpty() {
    assertEquals(new LinkedList<Integer>(), E.reverseCopy(new ArrayList<Integer>()));
  }
  public void testListReverseTypical() {
    List<Integer> list = new ArrayList<Integer>();
    for (int i=0; i<5; i++) {
      list.add(new Integer(128 + i));
    }
    List<Integer> result = E.reverseCopy(list);
    assertEquals(5, result.size());
    for (int i=0; i<5; i++) {
      assertEquals(list.get(i), result.get(4-i));
    }
  }
}

