package hirondelle.web4j.model;

import junit.framework.*;
//import junit.ui.TestRunner;
//import junit.textui.TestRunner;
//import junit.swingui.TestRunner;
import java.util.*;

/**
 <a href="http://www.junit.org">JUnit</a> test cases for {@link ModelUtil}.
*/
public final class TESTEqualsUtil extends TestCase {

  /**
   Run the test cases.
  */
   public static void main(String args[]) {
     String[] testCaseName = { TESTEqualsUtil.class.getName()};
     //Select one of several types of interfaces.
     junit.textui.TestRunner.main(testCaseName);
     //junit.swingui.TestRunner.main(testCaseName);
     //junit.ui.TestRunner.main(testCaseName);
  }

  /**
   Canonical form of constructor.
  */
  public TESTEqualsUtil( String aName) {
   super( aName );
  }

  // TEST CASES //
  
  public void testBoolean(){
    assertTrue( ModelUtil.areEqual(true, true) );
    assertTrue( ModelUtil.areEqual(false, false) );
    assertTrue( !ModelUtil.areEqual(false, true) );
    assertTrue( !ModelUtil.areEqual(true, false) );
  }
  
  public void testChar(){
    assertTrue( ModelUtil.areEqual('A', 'A') );
    assertTrue( ! ModelUtil.areEqual('A', 'B') );
  }
  
  public void testByte(){
    byte zero = 0;
    byte one = 1;
    assertTrue( ModelUtil.areEqual(one, one) );
    assertTrue( ! ModelUtil.areEqual(one, zero) );
  }

  public void testShort(){
    short ten = 10;
    short twenty = 20;
    assertTrue( ModelUtil.areEqual(ten, ten) );
    assertTrue( !ModelUtil.areEqual(ten, twenty) );
  }
  
  public void testInt(){
    int hundred = 100;
    int thousand = 1000;
    assertTrue( ModelUtil.areEqual(hundred, hundred) );
    assertTrue( !ModelUtil.areEqual(hundred, thousand) );
  }
  
  public void testLong(){
    long hundred = 100;
    long thousand = 1000;
    assertTrue( ModelUtil.areEqual(hundred, hundred) );
    assertTrue( !ModelUtil.areEqual(hundred, thousand) );
  }
  
  public void testFloat(){
    float hundred = 100.0F;
    float thousand = 1000.0F;
    assertTrue( ModelUtil.areEqual(hundred, hundred) );
    assertTrue( !ModelUtil.areEqual(hundred, thousand) );
  }

  public void testDouble(){
    double hundred = 100.0D;
    double thousand = 1000.0D;
    assertTrue( ModelUtil.areEqual(hundred, hundred) );
    assertTrue( !ModelUtil.areEqual(hundred, thousand) );
  }
  
  public void testNullObject(){
    Object one = null;
    Object two = null;
    assertTrue( ModelUtil.areEqual(one, two) );
    one = new Object();
    assertTrue( ! ModelUtil.areEqual(one, two) );
  }
  
  public void testStrings(){
    testObjects("one", "one", Outcome.SUCCESS);
    testObjects("o", "o", Outcome.SUCCESS);
    testObjects("", "", Outcome.SUCCESS);
    testObjects(" ", " ", Outcome.SUCCESS);
    testObjects("  ",  "  ", Outcome.SUCCESS);
    testObjects("\u00E9",  "\u00E9", Outcome.SUCCESS);
    testObjects(" \u00E9",  " \u00E9", Outcome.SUCCESS);
    testObjects("\u00E9",  "é", Outcome.SUCCESS);
    
    testObjects("one", "two", Outcome.FAIL);
    testObjects("one", "one ", Outcome.FAIL);
    testObjects("one", " one", Outcome.FAIL);
    testObjects("", " ", Outcome.FAIL);
    testObjects("\u00E9",  "é ", Outcome.FAIL);
    testObjects("\u00E9",  "e", Outcome.FAIL);
  }
  
  public void testIntegers(){
    Integer one = new Integer(1);
    Integer two = new Integer(2);
    assertTrue( ModelUtil.areEqual(one, one) );
    assertTrue( ! ModelUtil.areEqual(one, two) );
  }
  
  public void testLists(){
    List<String> bands = new ArrayList<String>();
    bands.add("French Funk Federation");
    bands.add("Les Rita Mitsouko");
    
    List<String> books = new ArrayList<String>();
    books.add("L'Education Sentimentale");
    
    List<String> books2 = new ArrayList<String>();
    books2.add("L'Education Sentimentale");
    
    List<String> books3 = new ArrayList<String>();
    books3.add(" L'Education Sentimentale");
    
    testObjects(bands, bands, Outcome.SUCCESS);
    testObjects(books, books, Outcome.SUCCESS);
    testObjects(books, books2, Outcome.SUCCESS);
    
    testObjects(bands, books, Outcome.FAIL);
    testObjects(books, books3, Outcome.FAIL);
    testObjects(bands, null, Outcome.FAIL);
  }
  
  public void testArrays(){
    String[] a = {"1"};
    String[] a2 = {"1"};
    String[] b = {"1 "};
    String[] c = {"1", "2"};
    String[] c2 = {"1", "2"};
    String[] d = {"1", "2 "};
    testObjects(a, a, Outcome.SUCCESS);
    testObjects(a, a2, Outcome.SUCCESS);
    testObjects(a, b, Outcome.FAIL);
    testObjects(c, c2, Outcome.SUCCESS);
    testObjects(null, null, Outcome.SUCCESS);
    
    testObjects(c, d, Outcome.FAIL);
    testObjects(c, null, Outcome.FAIL);
    
    //nested arrays
    Object[] n1 = {a, c};
    Object[] n2 = {a2, c2};
    Object[] n3 = {a2, d};
    testObjects(n1, n2, Outcome.SUCCESS);
    testObjects(n1, n3, Outcome.FAIL);
  }
  
  // FIXTURE //

  /**
   Build a fixture of test objects. This method is called anew for
   each test, such that the tests will always start with the same
   set of test objects, and the execution of one test will not interfere
   with the execution of another.
  */
   protected void setUp(){
   }

   /**
    Re-set test objects.
   */
   protected void tearDown() {
   }

   // PRIVATE  //
   
   private enum Outcome {SUCCESS, FAIL};
   
   private void testObjects(Object a, Object b, Outcome outcome){
     if (Outcome.SUCCESS == outcome){
       assertTrue(ModelUtil.areEqual(a, b));
     }
     else {
       assertFalse(ModelUtil.areEqual(a, b));
     }
   }
}
