package highOrder;

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

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class TestReduce extends TestCase {
  public TestReduce(String name) {
    super(name);
  }

  public static Test suite() {
    return new TestSuite(TestReduce.class);
  }

  /**
   * Test if we can sum a list properly.
   * 
   * @throws Exception
   *         in case something goes wrong.
   */
  public void testSum() throws Exception {
    List<Integer> l0 = new LinkedList<Integer>();
    for (int i = 0; i < 16384; i++) {
      l0.add(i);
    }
    Reducer<Integer, Integer> r = new Reducer<Integer, Integer>() {
      @Override
      public Integer binOp(Integer e, Integer acc) {
        return e + acc;
      }
    };
    Integer i1 = r.reduce(l0, 0);
    assertEquals((int)i1, 16383 * (16384 / 2));
  }

  /**
   * Test if we can sum an empty list.
   * 
   * @throws Exception
   *         in case something goes wrong.
   */
  public void testSum0() throws Exception {
    List<Integer> l0 = new LinkedList<Integer>();
    Reducer<Integer, Integer> r = new Reducer<Integer, Integer>() {
      @Override
      public Integer binOp(Integer e, Integer acc) {
        return e + acc;
      }
    };
    Integer i1 = r.reduce(l0, 0);
    assertEquals((int)i1, 0);
  }

  /**
   * Test if we can count the number of occurrences of characters in a list of
   * strings.
   * 
   * @throws Exception
   *         in case something goes wrong.
   */
  public void testCountChar() throws Exception {
    List<String> l0 = new LinkedList<String>();
    for (int i = 0; i < 1024; i++) {
      l0.add("aba");
    }
    Reducer<String, char[]> r = new Reducer<String, char[]>() {
      @Override
      public char[] binOp(String e, char[] acc) {
        for (int i = 0; i < e.length(); i++) {
          acc[e.charAt(i)]++;
        }
        return acc;
      }
    };
    char acc[] = new char[128];
    char res[] = r.reduce(l0, acc);
    assertEquals(res.length, 128);
    assertEquals(res['a'], 2048);
    assertEquals(res['b'], 1024);
    assertEquals(res['A'], 0);
  }
}
