package nxm.sys.test.junit.lib;

import org.junit.AfterClass;
import org.junit.BeforeClass;

import nxm.sys.lib.Data;
import nxm.sys.lib.Midas;
import nxm.sys.lib.Table;
import nxm.sys.lib.XMValue;
import nxm.sys.lib.XMValue.Backend;
import nxm.sys.test.junit.NMTestCase;

/** This will test the XMValueTest class.
    @author  J. Czechowski IV
    @since   NeXtMidas 2.7.1
 */
public final class XMValueTest extends NMTestCase {
  /** public constructor to allow running this test case directly with JUnit. */
  public XMValueTest (String methodName) { this(methodName,null); }

  /** Creates a new instance of the class.
      @param methodName The name of the method being called.
      @param midas      The midas context to use when running the tests.
   */
  public XMValueTest(String methodName, Midas midas) {
    super(methodName, midas);
  }

  private static XMValue ONE;
  private static XMValue TWO;
  private static XMValue THREE;

  /** Initialize XMValues before running tests
   *  @since NeXtMidas 4.1.4
   */
  @BeforeClass
  public void setUp() {
    ONE   = new XMValue(1);
    TWO   = new XMValue(2);
    THREE = new XMValue(3);
  }

  public void testConstants() {
    // since 3.7.0, moved these XMValue static initializer checks into this test case.
    // check to make sure that the type letter match those used in X-Midas.
    // If any of these fail, it means that someone changed the XMValue constants
    // or ones in DataTypes.java without proper coordination.
    assertEquals("XMValue.NONE",    ' ', XMValue.NONE);
    assertEquals("XMValue.ASCII",   'A', XMValue.ASCII);
    assertEquals("XMValue.ASCII256",'Z', XMValue.ASCII256);
    assertEquals("XMValue.INT_1",   'B', XMValue.INT_1);
    assertEquals("XMValue.INT_U1",  'O', XMValue.INT_U1);
    assertEquals("XMValue.INT_2",   'I', XMValue.INT_2);
    assertEquals("XMValue.INT_4",   'L', XMValue.INT_4);
    assertEquals("XMValue.INT_8",   'X', XMValue.INT_8);
    assertEquals("XMValue.REAL_4",  'F', XMValue.REAL_4);
    assertEquals("XMValue.REAL_8",  'D', XMValue.REAL_8);
    assertEquals("XMValue.LIST",    'C', XMValue.LIST);
    assertEquals("XMValue.KVLIST",  'K', XMValue.KVLIST);
    assertEquals("XMValue.TABLE",   'H', XMValue.TABLE);
    assertEquals("XMValue.XMVALUE", 'V', XMValue.XMVALUE);
  }

  public void testGetDefaultBackend () {
    Class<? extends Backend> clazz = XMValue.getDefaultBackend();
    assertNotNull("getDefaultBackend()", clazz);
    info("Testing XMValue with backend "+clazz);
  }

  public void testSetDefaultBackend () { } // internal method, no tests
  public void testGetBackend () { } // internal method, no tests
  public void testSetBackend () { } // internal method, no tests

  public void testToXMValue () {
    Object  obj;
    XMValue act;
    XMValue exp;

    // Automatic null -> None
    obj = null;
    exp = new XMValue();
    act = XMValue.toXMValue(obj);
    assertEquals("toXMValue("+obj+")", exp, act);
    XMValue.delete(exp,act); // free any native pointers

    // Automatic None -> None
    obj = "None";
    exp = new XMValue();
    act = XMValue.toXMValue(obj);
    assertEquals("toXMValue("+obj+")", exp, act);
    XMValue.delete(exp,act); // free any native pointers

    // Automatic Number
    obj = new Data(3.14);
    exp = new XMValue(3.14);
    act = XMValue.toXMValue(obj);
    assertEquals("toXMValue("+obj+")", exp, act);
    XMValue.delete(exp,act); // free any native pointers

    // Automatic String -> Number
    obj = "3.14";
    exp = new XMValue(); exp.setValue(3.14);
    act = XMValue.toXMValue(obj);
    assertEquals("toXMValue("+obj+")", exp, act);
    XMValue.delete(exp,act); // free any native pointers

    // Automatic String -> ASCII
    obj = "Hello World!";
    exp = new XMValue("Hello World!");
    act = XMValue.toXMValue(obj);
    assertEquals("toXMValue("+obj+")", exp, act);
    XMValue.delete(exp,act); // free any native pointers

    // Automatic Table
    Table tbl = new Table();          tbl.put("A", ONE); tbl.put("B", TWO); tbl.put("C", THREE);
    obj = tbl;
    exp = new XMValue(XMValue.TABLE); exp.put("A", ONE); exp.put("B", TWO); exp.put("C", THREE);
    act = XMValue.toXMValue(obj);
    assertEquals("toXMValue("+obj+")", exp, act);
    XMValue.delete(exp,act); // free any native pointers
  }

  public void testEquals () {
    // TODO
  }

  public void testHashCode () { } // Tested in testEquals()

  public void testToString () {
    XMValue val;
    String  exp;
    String  act;

    val = new XMValue();
    exp = "None";
    act = val.toString();
    assertEquals("toString() for "+val, exp, act);
    val.delete(); // free any native pointer

    val = new XMValue(3.14);
    exp = "3.14";
    act = val.toString();
    assertEquals("toString() for "+val, exp, act);
    val.delete(); // free any native pointer

    val = new XMValue("Hello World!");
    exp = "Hello World!";
    act = val.toString();
    assertEquals("toString() for "+val, exp, act);
    val.delete(); // free any native pointer

    int[] array = new int[] { 1, 2, 3 };
    val = new XMValue(array);
    exp = "(1,2,3)";
    act = val.toString();
    assertEquals("toString() for "+val, exp, act);
    val.delete(); // free any native pointer

    val = new XMValue(XMValue.LIST); val.append(ONE); val.append(TWO); val.append(THREE);
    exp = "[L:1,L:2,L:3]";
    act = val.toString();
    assertEquals("toString() for "+val, exp, act);
    val.delete(); // free any native pointer

    val = new XMValue(XMValue.KVLIST); val.put("A",ONE); val.put("B",TWO); val.put("C",THREE);
    exp = "{L:A=1,L:B=2,L:C=3}";
    act = val.toString();
    assertEquals("toString() for "+val, exp, act);
    val.delete(); // free any native pointer

    val = new XMValue(XMValue.TABLE); val.put("A",ONE); val.put("B",TWO); val.put("C",THREE);
    exp = "{L:A=1,L:B=2,L:C=3}";
    act = val.toString();
    assertEquals("toString() for "+val, exp, act);
    val.delete(); // free any native pointer
  }

  public void testSetValue () {
    XMValue val     = new XMValue();
    XMValue tempVal = new XMValue(3.14);

    val.setValue("3.14");         assertEquals("setValue(3.14) with String", "3.14", val.toA());
    val.setValue(tempVal);        assertEquals("setValue(3.14) with XMValue", 3.14,  val.toD());
    val.setValue(new Data(3.14)); assertEquals("setValue(3.14) with Data ",   3.14,  val.toD());
    val.setValue(3.14);           assertEquals("setValue(3.14) with double ", 3.14,  val.toD());
    val.setValue(3.14f);          assertEquals("setValue(3.14) with float ",  3.14f, val.toF());
    val.setValue((long)3);        assertEquals("setValue(3)    with long ",   3,     val.toD());
    val.setValue(3);              assertEquals("setValue(3)    with int ",    3,     val.toD());
    val.setValue((short)3);       assertEquals("setValue(3)    with short ",  3,     val.toD());
    val.setValue((byte)3);        assertEquals("setValue(3)    with byte ",   3,     val.toD());

    XMValue.delete(val,tempVal); // free any native pointers
  }

  public void testGetType () {
    XMValue val     = new XMValue();
    XMValue tempVal = new XMValue(3.14);

    val.setValue("3.14");         assertEquals("getType()", XMValue.ASCII,  val.getFormatType());
    val.setValue(tempVal);        assertEquals("getType()", XMValue.REAL_8, val.getFormatType());
    val.setValue(new Data(3.14)); assertEquals("getType()", XMValue.REAL_8, val.getFormatType());
    val.setValue(3.14);           assertEquals("getType()", XMValue.REAL_8, val.getFormatType());
    val.setValue((float)3.14);    assertEquals("getType()", XMValue.REAL_4, val.getFormatType());
    val.setValue((long)3);        assertEquals("getType()", XMValue.INT_8,  val.getFormatType());
    val.setValue(3);              assertEquals("getType()", XMValue.INT_4,  val.getFormatType());
    val.setValue((short)3);       assertEquals("getType()", XMValue.INT_2,  val.getFormatType());
    val.setValue((byte)3);        assertEquals("getType()", XMValue.INT_1,  val.getFormatType());

    XMValue.delete(val,tempVal);
  }

  /** Gets the full string name for the given XMValue type.
      @return The type name.
   */
  public void testGetTypeName () {
    char[]    TYPES     = { XMValue.NONE,   XMValue.ASCII,  //XMValue.ASCII256, // skip ASCII256 test until X-Midas ready
                            XMValue.INT_1,  XMValue.INT_U1, XMValue.INT_2,  XMValue.INT_4,  XMValue.INT_8,
                            XMValue.REAL_4, XMValue.REAL_8,
                            XMValue.LIST,   XMValue.KVLIST, XMValue.TABLE };
    String[]  NAMES     = { "None",         "ASCII",       // "ASCII256",
                            "int_1",        "int_u1",       "int_2",        "int_4",        "int_8",
                            "real_4",       "real_8",
                            "List",         "KVList",       "Table" };
    boolean[] NUMERIC   = { false,          false,       //   false,
                            true,           true,           true,           true,           true,
                            true,           true,
                            false,          false,          false };
    boolean[] BASIC     = { false,          true,         //  true,
                            true,           true,           true,           true,           true,
                            true,           true,
                            false,          false,          false };
    boolean[] CONTAINER = { false,          false,       //   false,
                            false,          false,          false,          false,          false,
                            false,          false,
                            true,           true,           true };
    boolean[] STRINGKEY = { false,          false,       //   false,
                            false,          false,          false,          false,          false,
                            false,          false,
                            false,          true,           true };


    for (int i = 0; i < TYPES.length; i++) {
      XMValue val = new XMValue(TYPES[i]);
      assertEquals("val.getTypeName()",             NAMES[i],      val.getTypeName());
      assertEquals("val.isNumericType()",           NUMERIC[i],    val.isNumericType());
      assertEquals("val.isBasicType()",             BASIC[i],      val.isBasicType());
      assertEquals("val.isContainer()",             CONTAINER[i],  val.isContainer());
      assertEquals("val.isStringKeyed()",           STRINGKEY[i],  val.isStringKeyed());
      val.delete(); // free any native pointer

      assertEquals("getTypeName("+TYPES[i]+")",     NAMES[i],      XMValue.getTypeName(TYPES[i]));
      assertEquals("isNumericType("+TYPES[i]+")",   NUMERIC[i],    XMValue.isNumericType(TYPES[i]));
      assertEquals("isBasicType("+TYPES[i]+")",     BASIC[i],      XMValue.isBasicType(TYPES[i]));
      assertEquals("isContainer("+TYPES[i]+")",     CONTAINER[i],  XMValue.isContainer(TYPES[i]));
      assertEquals("isStringKeyed("+TYPES[i]+")",   STRINGKEY[i],  XMValue.isStringKeyed(TYPES[i]));
      assertEquals("isLegalTypeChar("+TYPES[i]+")", true,          XMValue.isLegalType(TYPES[i]));
    }

    // Check all possible ASCII values and make sure that any that aren't valid report as such.
    for (char c = 0; c <= 0x7f; c++) {
      boolean valid = false;
      for (int i = 0; i < TYPES.length; i++) {
        if (TYPES[i] == c) {
          valid = true;
          break;
        }
      }

      if (c == XMValue.ASCII256) valid=true; // in holding pattern waiting for X-Midas

      if (!valid) {
        assertEquals("getTypeName("+c+")",     "Unknown",  XMValue.getTypeName(c));
        assertEquals("isNumericType("+c+")",   false,      XMValue.isNumericType(c));
        assertEquals("isBasicType("+c+")",     false,      XMValue.isBasicType(c));
        assertEquals("isContainer("+c+")",     false,      XMValue.isContainer(c));
        assertEquals("isStringKeyed("+c+")",   false,      XMValue.isStringKeyed(c));
        assertEquals("isLegalTypeChar("+c+")", false,      XMValue.isLegalType(c));
      }
    }

  }

  public final void testIsNumericType () { }    // tested in testGetTypeName()
  public final void testIsBasicType () { }      // tested in testGetTypeName()
  public final void testIsContainer () { }      // tested in testGetTypeName()
  public final void testIsStringKeyed () { }    // tested in testGetTypeName()
  public final void testIsLegalType () { }      // tested in testGetTypeName()

  public void testCopy () {
    XMValue val = new XMValue();
    XMValue copy;

    // The copy must be a new instance that is equal to the original
    val.setValue(3.14);        copy=val.copy(); assertEquals("copy()",val,copy); assertNotSame("not same",val,copy); copy.delete();
    val.setValue((float)3.14); copy=val.copy(); assertEquals("copy()",val,copy); assertNotSame("not same",val,copy); copy.delete();
    val.setValue((long)3);     copy=val.copy(); assertEquals("copy()",val,copy); assertNotSame("not same",val,copy); copy.delete();
    val.setValue(3);           copy=val.copy(); assertEquals("copy()",val,copy); assertNotSame("not same",val,copy); copy.delete();
    val.setValue((short)3);    copy=val.copy(); assertEquals("copy()",val,copy); assertNotSame("not same",val,copy); copy.delete();
    val.setValue((byte)3);     copy=val.copy(); assertEquals("copy()",val,copy); assertNotSame("not same",val,copy); copy.delete();

    val.delete(); // free any native pointer
  }

  public void testSize () {
    for (int i = 0; i < 16; i++) {
      boolean empty = (i == 0);

      double[] dval = new double[i];
      float[]  fval = new float[i];
      long[]   xval = new long[i];
      int[]    lval = new int[i];
      short[]  ival = new short[i];
      byte[]   bval = new byte[i];

      for (int j = 0; j < i; j++) {
        dval[j] = j;
        fval[j] = j;
        xval[j] = j;
        lval[j] = j;
        ival[j] = (short)j;
        bval[j] = (byte)j;
      }

      XMValue dv = new XMValue(dval);
      XMValue fv = new XMValue(fval);
      XMValue xv = new XMValue(xval);
      XMValue lv = new XMValue(lval);
      XMValue iv = new XMValue(ival);
      XMValue bv = new XMValue(bval);

      assertEquals("dv.getSize() for i="+i, i, dv.getSize());
      assertEquals("fv.getSize() for i="+i, i, fv.getSize());
      assertEquals("xv.getSize() for i="+i, i, xv.getSize());
      assertEquals("lv.getSize() for i="+i, i, lv.getSize());
      assertEquals("iv.getSize() for i="+i, i, iv.getSize());
      assertEquals("bv.getSize() for i="+i, i, bv.getSize());


      assertEquals("dv.size() for i="+i, i, dv.size());
      assertEquals("fv.size() for i="+i, i, fv.size());
      assertEquals("xv.size() for i="+i, i, xv.size());
      assertEquals("lv.size() for i="+i, i, lv.size());
      assertEquals("iv.size() for i="+i, i, iv.size());
      assertEquals("bv.size() for i="+i, i, bv.size());

      assertEquals("dv.isEmpty() for i="+i, empty, dv.isEmpty());
      assertEquals("fv.isEmpty() for i="+i, empty, fv.isEmpty());
      assertEquals("xv.isEmpty() for i="+i, empty, xv.isEmpty());
      assertEquals("lv.isEmpty() for i="+i, empty, lv.isEmpty());
      assertEquals("iv.isEmpty() for i="+i, empty, iv.isEmpty());
      assertEquals("bv.isEmpty() for i="+i, empty, bv.isEmpty());

      XMValue.delete(dv,fv,xv,lv,iv,bv);
    }
  }

  public void testGetSize () { } // tested in testSize()
  public void testIsEmpty () { } // tested in testSize()

  public void testGet () {
    // get(int)
    for (int i = 0; i < 16; i++) {
      double[] dval = new double[i];
      float[]  fval = new float[i];
      long[]   xval = new long[i];
      int[]    lval = new int[i];
      short[]  ival = new short[i];
      byte[]   bval = new byte[i];

      for (int j = 0; j < i; j++) {
        dval[j] = j;
        fval[j] = j;
        xval[j] = j;
        lval[j] = j;
        ival[j] = (short)j;
        bval[j] = (byte)j;
      }

      XMValue dv = new XMValue(dval);
      XMValue fv = new XMValue(fval);
      XMValue xv = new XMValue(xval);
      XMValue lv = new XMValue(lval);
      XMValue iv = new XMValue(ival);
      XMValue bv = new XMValue(bval);

      XMValue tempVal = null;
      XMValue getVal = null;

      for (int j = 1; j <= i; j++) {
        tempVal = new XMValue(dval[j-1]); getVal = dv.get(j); assertEquals("dv.get("+j+")", tempVal, getVal); XMValue.delete(tempVal,getVal);
        tempVal = new XMValue(fval[j-1]); getVal = fv.get(j); assertEquals("fv.get("+j+")", tempVal, getVal); XMValue.delete(tempVal,getVal);
        tempVal = new XMValue(xval[j-1]); getVal = xv.get(j); assertEquals("xv.get("+j+")", tempVal, getVal); XMValue.delete(tempVal,getVal);
        tempVal = new XMValue(lval[j-1]); getVal = lv.get(j); assertEquals("lv.get("+j+")", tempVal, getVal); XMValue.delete(tempVal,getVal);
        tempVal = new XMValue(ival[j-1]); getVal = iv.get(j); assertEquals("iv.get("+j+")", tempVal, getVal); XMValue.delete(tempVal,getVal);
        tempVal = new XMValue(bval[j-1]); getVal = bv.get(j); assertEquals("bv.get("+j+")", tempVal, getVal); XMValue.delete(tempVal,getVal);
      }

      XMValue.delete(dv,fv,xv,lv,iv,bv); // free any native pointers
    }

    // get(String)
    XMValue k = new XMValue(XMValue.KVLIST);  k.put("A",ONE);  k.put("B",TWO);  k.put("C",THREE);
    XMValue t = new XMValue(XMValue.TABLE);   t.put("A",ONE);  t.put("B",TWO);  t.put("C",THREE);

    assertEquals("k.get('A')", ONE,   k.get("A"));
    assertEquals("k.get('B')", TWO,   k.get("B"));
    assertEquals("k.get('C')", THREE, k.get("C"));

    assertEquals("t.get('A')", ONE,   t.get("A"));
    assertEquals("t.get('B')", TWO,   t.get("B"));
    assertEquals("t.get('C')", THREE, t.get("C"));

    XMValue.delete(k,t); // free any native pointers
  }

  public void testSet () {
    // TODO
    // set(int,XMValue), set(int,Object)


    // set(String,XMValue) or put(String,XMValue)
    // set(String,Object) or put(String,Object)

  }

  public void testPut () { } // tested in testSet()

  public void testContainsKey () {
    XMValue k = new XMValue(XMValue.KVLIST);  k.put("A",ONE);  k.put("B",TWO);  k.put("C",THREE);
    XMValue t = new XMValue(XMValue.TABLE);   t.put("A",ONE);  t.put("B",TWO);  t.put("C",THREE);

    assertTrue( "k.containsKey('A')", k.containsKey("A"));    assertTrue( "t.containsKey('A')", t.containsKey("A"));
    assertTrue( "k.containsKey('B')", k.containsKey("B"));    assertTrue( "t.containsKey('B')", t.containsKey("B"));
    assertTrue( "k.containsKey('C')", k.containsKey("C"));    assertTrue( "t.containsKey('C')", t.containsKey("C"));
    assertFalse("k.containsKey('D')", k.containsKey("D"));    assertFalse("t.containsKey('D')", t.containsKey("D"));
    assertFalse("k.containsKey('E')", k.containsKey("E"));    assertFalse("t.containsKey('E')", t.containsKey("E"));
    assertFalse("k.containsKey('F')", k.containsKey("F"));    assertFalse("t.containsKey('F')", t.containsKey("F"));

    XMValue.delete(k,t); // free any native pointers
  }

  public void testAppend () {
    // TODO
    // append(XMValue)

    // append(KVPair)
  }

  public void testMerge () {
    // TODO
  }

  public void testUpdate () {
    // TODO
  }

  public void testClear () {
    XMValue k = new XMValue(XMValue.KVLIST);  k.put("A",ONE);  k.put("B",TWO);  k.put("C",THREE);
    XMValue t = new XMValue(XMValue.TABLE);   t.put("A",ONE);  t.put("B",TWO);  t.put("C",THREE);

    assertEquals("k.size()", 3, k.size());                   assertEquals("t.size()", 3, t.size());
    assertFalse("k.isEmpty()", k.isEmpty());                 assertFalse("t.isEmpty()", t.isEmpty());
    assertTrue("k.containsKey('A')", k.containsKey("A"));    assertTrue("t.containsKey('A')", t.containsKey("A"));
    assertTrue("k.containsKey('B')", k.containsKey("B"));    assertTrue("t.containsKey('B')", t.containsKey("B"));
    assertTrue("k.containsKey('C')", k.containsKey("C"));    assertTrue("t.containsKey('C')", t.containsKey("C"));

    k.clear();                                               t.clear();
    assertEquals("k.size()", 0, k.size());                   assertEquals("t.size()", 0, t.size());
    assertTrue("k.isEmpty()", k.isEmpty());                  assertTrue("t.isEmpty()", t.isEmpty());
    assertFalse("k.containsKey('A')", k.containsKey("A"));   assertFalse("t.containsKey('A')", t.containsKey("A"));
    assertFalse("k.containsKey('B')", k.containsKey("B"));   assertFalse("t.containsKey('B')", t.containsKey("B"));
    assertFalse("k.containsKey('C')", k.containsKey("C"));   assertFalse("t.containsKey('C')", t.containsKey("C"));

    XMValue.delete(k,t); // free any native pointers
  }

  public void testVectorize () {
    // not quite sure how to best test this...

  }

  public void testTablize () {
    XMValue k = new XMValue(XMValue.KVLIST);  k.put("A",ONE);  k.put("B",TWO);  k.put("C",THREE);
    XMValue t = new XMValue(XMValue.TABLE);   t.put("A",ONE);  t.put("B",TWO);  t.put("C",THREE);
    XMValue kt = k.tablize();
    XMValue tt = t.tablize();

    assertEquals("k.tablize()", t, kt);
    assertEquals("t.tablize()", t, tt);
    XMValue.delete(k,t,kt,tt); // free any native pointers
  }

  public void testKeys () {
    XMValue k = new XMValue(XMValue.KVLIST);  k.put("A",ONE);  k.put("B",TWO);  k.put("C",THREE);
    XMValue t = new XMValue(XMValue.TABLE);   t.put("A",ONE);  t.put("B",TWO);  t.put("C",THREE);

    XMValue kk = k.keys();                                       XMValue tk = t.keys();
    assertEquals("k.keys().size()",  3,  kk.size());             assertEquals("t.keys().size()",  3,  tk.size());
    assertEquals("k.keys().get(1)", "A", kk.get(1).toString());  assertEquals("t.keys().get(1)", "A", tk.get(1).toString());
    assertEquals("k.keys().get(2)", "B", kk.get(2).toString());  assertEquals("t.keys().get(2)", "B", tk.get(2).toString());
    assertEquals("k.keys().get(3)", "C", kk.get(3).toString());  assertEquals("t.keys().get(3)", "C", tk.get(3).toString());

    XMValue.delete(k,t,kk,tk); // free any native pointers
  }

  public void testItems () {
    XMValue k = new XMValue(XMValue.KVLIST);  k.put("A",ONE);  k.put("B",TWO);  k.put("C",THREE);
    XMValue t = new XMValue(XMValue.TABLE);   t.put("A",ONE);  t.put("B",TWO);  t.put("C",THREE);
    XMValue ki = k.items();
    XMValue ti = t.items();

    assertEquals("k.items()", k, ki);
    assertEquals("t.items()", k, ti);

    XMValue.delete(k,t,ki,ti);
  }

  public void testToD () {
    double[] VALUES = { 0, -42, 42, 3.14, 86 };

    XMValue val = new XMValue();

    for (int index = 0; index < VALUES.length; index++) {
      double v        = VALUES[index];
      XMValue tempVal = new XMValue(v);

      double d = v;
      val.setValue(tempVal);     assertEquals("toD() with XMValue "+v,        d, val.toD());
      val.setValue(new Data(v)); assertEquals("toD() with Data "   +v,        d, val.toD());
      val.setValue(v);           assertEquals("toD() with double " +v,        d, val.toD());
      val.setValue((float)v);    assertEquals("toD() with float "  +v, (float)d, val.toD());
      val.setValue((long)v);     assertEquals("toD() with long "   +v, (long) d, val.toD());
      val.setValue((int)v);      assertEquals("toD() with int "    +v, (int)  d, val.toD());
      val.setValue((short)v);    assertEquals("toD() with short "  +v, (short)d, val.toD());
      val.setValue((byte)v);     assertEquals("toD() with byte "   +v, (byte) d, val.toD());

      float f = (float)v;
      val.setValue(tempVal);     assertEquals("toF() with XMValue "+v,        f, val.toF());
      val.setValue(new Data(v)); assertEquals("toF() with Data "   +v,        f, val.toF());
      val.setValue(v);           assertEquals("toF() with double " +v,        f, val.toF());
      val.setValue((float)v);    assertEquals("toF() with float "  +v,        f, val.toF());
      val.setValue((long)v);     assertEquals("toF() with long "   +v, (long) f, val.toF());
      val.setValue((int)v);      assertEquals("toF() with int "    +v, (int)  f, val.toF());
      val.setValue((short)v);    assertEquals("toF() with short "  +v, (short)f, val.toF());
      val.setValue((byte)v);     assertEquals("toF() with byte "   +v, (byte) f, val.toF());

      long x = (long)v;
      val.setValue(tempVal);     assertEquals("toX() with XMValue "+v,        x, val.toX());
      val.setValue(new Data(v)); assertEquals("toX() with Data "   +v,        x, val.toX());
      val.setValue(v);           assertEquals("toX() with double " +v,        x, val.toX());
      val.setValue((float)v);    assertEquals("toX() with float "  +v,        x, val.toX());
      val.setValue((long)v);     assertEquals("toX() with long "   +v,        x, val.toX());
      val.setValue((int)v);      assertEquals("toX() with int "    +v, (int)  x, val.toX());
      val.setValue((short)v);    assertEquals("toX() with short "  +v, (short)x, val.toX());
      val.setValue((byte)v);     assertEquals("toX() with byte "   +v, (byte) x, val.toX());

      int l = (int)v;
      val.setValue(tempVal);     assertEquals("toL() with XMValue "+v,        l, val.toL());
      val.setValue(new Data(v)); assertEquals("toL() with Data "   +v,        l, val.toL());
      val.setValue(v);           assertEquals("toL() with double " +v,        l, val.toL());
      val.setValue((float)v);    assertEquals("toL() with float "  +v,        l, val.toL());
      val.setValue((long)v);     assertEquals("toL() with long "   +v,        l, val.toL());
      val.setValue((int)v);      assertEquals("toL() with int "    +v,        l, val.toL());
      val.setValue((short)v);    assertEquals("toL() with short "  +v, (short)l, val.toL());
      val.setValue((byte)v);     assertEquals("toL() with byte "   +v, (byte) l, val.toL());

      short i = (short)v;
      val.setValue(tempVal);     assertEquals("toI() with XMValue "+v,        i, val.toI());
      val.setValue(new Data(v)); assertEquals("toI() with Data "   +v,        i, val.toI());
      val.setValue(v);           assertEquals("toI() with double " +v,        i, val.toI());
      val.setValue((float)v);    assertEquals("toI() with float "  +v,        i, val.toI());
      val.setValue((long)v);     assertEquals("toI() with long "   +v,        i, val.toI());
      val.setValue((int)v);      assertEquals("toI() with int "    +v,        i, val.toI());
      val.setValue((short)v);    assertEquals("toI() with short "  +v,        i, val.toI());
      val.setValue((byte)v);     assertEquals("toI() with byte "   +v, (byte) i, val.toI());

      byte b = (byte)v;
      val.setValue(tempVal);     assertEquals("toB() with XMValue "+v,        b, val.toB());
      val.setValue(new Data(v)); assertEquals("toB() with Data "   +v,        b, val.toB());
      val.setValue(v);           assertEquals("toB() with double " +v,        b, val.toB());
      val.setValue((float)v);    assertEquals("toB() with float "  +v,        b, val.toB());
      val.setValue((long)v);     assertEquals("toB() with long "   +v,        b, val.toB());
      val.setValue((int)v);      assertEquals("toB() with int "    +v,        b, val.toB());
      val.setValue((short)v);    assertEquals("toB() with short "  +v,        b, val.toB());
      val.setValue((byte)v);     assertEquals("toB() with byte "   +v,        b, val.toB());

      val.setValue(tempVal);     assertEquals("toA() with XMValue "+v, noDotZero(Double.toString(d) ), noDotZero(val.toA()));
      val.setValue(new Data(v)); assertEquals("toA() with Data "   +v, noDotZero(Double.toString(d) ), noDotZero(val.toA()));
      val.setValue(v);           assertEquals("toA() with double " +v, noDotZero(Double.toString(d) ), noDotZero(val.toA()));
      val.setValue((float)v);    assertEquals("toA() with float "  +v, noDotZero(Float.toString(f)  ), noDotZero(val.toA()));
      val.setValue((long)v);     assertEquals("toA() with long "   +v, noDotZero(Long.toString(x)   ), noDotZero(val.toA()));
      val.setValue((int)v);      assertEquals("toA() with int "    +v, noDotZero(Integer.toString(l)), noDotZero(val.toA()));
      val.setValue((short)v);    assertEquals("toA() with short "  +v, noDotZero(Short.toString(i)  ), noDotZero(val.toA()));
      val.setValue((byte)v);     assertEquals("toA() with byte "   +v, noDotZero(Byte.toString(b)   ), noDotZero(val.toA()));

      tempVal.delete(); // free any native pointer
    }

    val.delete(); // free any native pointer
  }

  /** Strip off any ".0" */
  private static String noDotZero (String str) {
    return (str.endsWith(".0"))? str.substring(0,str.length()-2) : str;
  }

  public void testToF () { } // tested in testToD()
  public void testToX () { } // tested in testToD()
  public void testToL () { } // tested in testToD()
  public void testToI () { } // tested in testToD()
  public void testToB () { } // tested in testToD()
  public void testToA () { } // tested in testToD()


  /** Delete static XMValue objects after done running all tests
   *
   *  @since NeXtMidas 4.1.3 Initially cleanup() and static,
   *                         changed to tearDown() and instance in 4.1.4
   */
  @AfterClass
  public void tearDown() {
    XMValue.delete(ONE,TWO,THREE);
  }
}
