package simpledb;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import junit.framework.JUnit4TestAdapter;

import org.junit.Before;
import org.junit.Test;

import simpledb.systemtest.SimpleDbTestBase;

public class ImputeTest extends SimpleDbTestBase {

  int testWidth = 3;
  DbIterator scan;

  /**
   * Initialize each unit test
   */
  @Before public void setUp() {
	  this.scan = new TestUtil.MockScanWithMissing(-5, 5, testWidth);
  }

  /**
   * Unit test for Impute.getTupleDesc(). TupleDesc should be identical as before.
   */
  @Test public void getTupleDesc() {
	  Impute op = new ImputeTotallyRandom(scan);
	  TupleDesc expected = Utility.getTupleDesc(testWidth);
	  TupleDesc actual = op.getTupleDesc();
	  assertEquals(expected, actual);
  }

  /**
   * Unit tests for Impute.rewind(). This doesn't do much. We get the first tuple
   * and after a rewind, confirm that we get the same first tuple.
   */
  @Test public void rewindTotallyRandom() throws Exception {
	  Impute op = new ImputeTotallyRandom(scan);
	  op.open();
	  assertTrue(op.hasNext());
	  Tuple expected = op.next();
	  assertNotNull(expected);
	  
	  op.rewind();
	  assertTrue(op.hasNext());
	  Tuple actual = op.next();
	  assertTrue(TestUtil.compareTuples(expected, actual));
	  op.close();
  }

  @Test public void rewindRandom() throws Exception {
	  Impute op = new ImputeRandom(scan);
	  op.open();
	  assertTrue(op.hasNext());
	  Tuple expected = op.next();
	  assertNotNull(expected);
	  
	  op.rewind();
	  assertTrue(op.hasNext());
	  Tuple actual = op.next();
	  assertTrue(TestUtil.compareTuples(expected, actual));
	  op.close();
  }
  
  @Test public void imputeTotallyRandom() throws Exception {
	  Impute op = new ImputeTotallyRandom(scan);
	  op.open();
	  while (op.hasNext()){
		  Tuple t = op.next();
		  assertTrue(!t.hasMissingFields());
	  }
	  op.close();
  }

  @Test public void imputeRandom() throws Exception {
	  Impute op = new ImputeRandom(scan);
	  op.open();
	  while (op.hasNext()){
		  Tuple t = op.next();
		  assertTrue(!t.hasMissingFields());
	  }
	  op.close();
  }

  /**
   * JUnit suite target
   */
  public static junit.framework.Test suite() {
    return new JUnit4TestAdapter(ImputeTest.class);
  }
}

@@ -580,17 +580,17 @@
 r Impute
-.
+#
 getTuple
@@ -682,29 +682,153 @@
 Desc
-() %7B%0D%0A%09  Impute op = 
+TotallyRandom() %7B%0D%0A%09  getTupleDescDriver(new ImputeTotallyRandom(scan));%0D%0A  %7D%0D%0A  @Test public void getTupleDescRandom() %7B%0D%0A%09  getTupleDescDriver(
 new 
@@ -825,39 +825,32 @@
 river(new Impute
-Totally
 Random(scan);%0D%0A%09
@@ -841,25 +841,81 @@
 Random(scan)
-;
+);%0D%0A  %7D%0D%0A  %0D%0A  public void getTupleDescDriver(Impute op)%7B
 %0D%0A%09  TupleDe
@@ -1080,17 +1080,17 @@
 r Impute
-.
+#
 rewind()
@@ -1273,36 +1273,37 @@
 ption %7B%0D%0A%09  
-Impute op = 
+rewindDriver(
 new ImputeTo
@@ -1323,269 +1323,8 @@
 can)
-;%0D%0A%09  op.open();%0D%0A%09  assertTrue(op.hasNext());%0D%0A%09  Tuple expected = op.next();%0D%0A%09  assertNotNull(expected);%0D%0A%09  %0D%0A%09  op.rewind();%0D%0A%09  assertTrue(op.hasNext());%0D%0A%09  Tuple actual = op.next();%0D%0A%09  assertTrue(TestUtil.compareTuples(expected, actual));%0D%0A%09  op.close(
 );%0D%0A
@@ -1320,34 +1320,32 @@
 m(scan));%0D%0A  %7D%0D%0A
-%0D%0A
   @Test public v
@@ -1382,36 +1382,37 @@
 ption %7B%0D%0A%09  
-Impute op = 
+rewindDriver(
 new ImputeRa
@@ -1413,33 +1413,101 @@
 puteRandom(scan)
-;
+);%0D%0A  %7D%0D%0A  %0D%0A  public void rewindDriver(Impute op) throws Exception %7B
 %0D%0A%09  op.open();%0D
@@ -1750,24 +1750,29 @@
 p.close();%0D%0A
+%09  %0D%0A
   %7D%0D%0A  %0D%0A  @
@@ -1774,48 +1774,205 @@
 %0D%0A  
-@Test public void imputeTotallyRandom() 
+/**%0D%0A   * Unit tests for Impute#fetchNext(). We iterate through the tuples, some of%0D%0A   * which have missing values. We confirm that the imputed tuples do not have%0D%0A   * any missing values.%0D%0A   * @
 thro
@@ -1987,184 +1987,124 @@
 tion
- %7B
+%0D%0A   */
 %0D%0A
-%09
   
-Impute op = new ImputeTotallyRandom(scan);%0D%0A%09  op.open();%0D%0A%09  while (op.hasNext())%7B%0D%0A%09%09  Tuple t = op.next();%0D%0A%09%09  assertTrue(!t.hasMissingFields());%0D%0A%09  %7D%0D%0A%09  op.close(
+@Test public void imputeTotallyRandom() throws Exception %7B%0D%0A%09  imputeDriver(new ImputeTotallyRandom(scan)
 );%0D%0A
@@ -2108,18 +2108,16 @@
 ;%0D%0A  %7D%0D%0A
-%0D%0A
   @Test 
@@ -2170,20 +2170,21 @@
 %0A%09  
-I
+i
 mpute
- op = 
+Driver(
 new 
@@ -2201,17 +2201,158 @@
 om(scan)
-;
+);%0D%0A  %7D%0D%0A  %0D%0A  // TODO: Confirm that the fields that were not imputed are identical.%0D%0A  public void imputeDriver(Impute op) throws Exception %7B
 %0D%0A%09  op.

Refactor testing a bit