Files
jlibcom/unittest/com/jacob/com/VariantTest.java
2007-09-06 01:28:03 +00:00

483 lines
14 KiB
Java

package com.jacob.com;
import java.math.BigDecimal;
import java.util.Date;
import com.jacob.test.BaseTestCase;
/**
* runs through some of the get and set methods on Variant
*
* <p>
* May need to run with some command line options (including from inside Eclipse).
* Look in the docs area at the Jacob usage document for command line options.
*/
public class VariantTest extends BaseTestCase {
/**
* This verifies that toJavaObject() works for all of the
* main data types when they exist as a byRef version.
* <p>
* It compares the toJavaObject() for a byref against the
* toJavaObject() for the regular.
*
*/
public void testByRefToJavaObject(){
Variant v = null;
Variant vByRef = null;
v = new Variant(new Float(53.3),false);
vByRef = new Variant(new Float(53.3),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant(new Double(53.3),false);
vByRef = new Variant(new Double(53.3),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant(new Boolean(true),false);
vByRef = new Variant(new Boolean(true),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant(new Integer(53),false);
vByRef = new Variant(new Integer(53),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant(new Short((short)53),false);
vByRef = new Variant(new Short((short)53),true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
v = new Variant("53.33",false);
vByRef = new Variant("53.33",true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
// Ugh, you have to pick a magic number whose scale is less than 28
// 53.53 had a scale of 64 and 53.52 had a scale of 47
BigDecimal testDecimal = new BigDecimal(53.50);
v = new Variant(testDecimal,false);
vByRef = new Variant(testDecimal,true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
Date now = new Date();
v = new Variant(now,false);
vByRef = new Variant(now,true);
if (!v.toJavaObject().equals(vByRef.toJavaObject())){
fail(v.toString() + " could not make type "
+ v.getvt() +" and "+ vByRef.getvt()
+" java objects come out the same");
}
// need to do currency also
}
/**
* 4/2007 bug report toObject on dispatch tries to call getDispatchRef
* instead of getDispatch so toString() on dispatch blows up.
*
*/
public void testDispatchToJavaObject(){
Variant v2 = new Variant();
v2.putNothing();
// this test fails even though the exact same code below works fine
//v2.toJavaObject();
}
/**
* see what happens when we conver to by ref
*
*/
public void testSomeChangeVT(){
Variant v;
// the code shows e shouldn't need to use a returned Variant but the test says we do
Variant vConverted;
v = new Variant(53.3);
short originalVT = v.getvt();
short modifier;
modifier = Variant.VariantShort;
vConverted = v.changeType(modifier);
if (vConverted.getvt() != modifier){
fail("Failed to change Variant "+originalVT
+ " using mask "+modifier
+ " resulted in "+vConverted.getvt()
);
}
modifier = Variant.VariantString;
vConverted = v.changeType(modifier);
if (vConverted.getvt() != modifier){
fail("Failed to change Variant "+originalVT
+ " using mask "+modifier
+ " resulted in "+vConverted.getvt()
);
}
// can't convert to byref!
modifier = Variant.VariantByref | Variant.VariantShort;
vConverted = v.changeType(modifier);
if (vConverted.getvt() == modifier){
fail("Should not have been able to change Variant "+originalVT
+ " using mask "+modifier
+ " resulted in "+vConverted.getvt()
);
}
}
/**
* make sure variant with no backing store works.
*
*/
public void testUninitializedVariant(){
Variant v;
// Variants created without parameters are auto set to VariantEmpty
v = new Variant();
try {
if (v.getvt() == Variant.VariantEmpty){
// successful
// System.out.println("Variant initialized without parameters correctly set to empty");
} else {
throw new RuntimeException("getvt() on uninitialized variant shoud have returned VariantEmpty, instead returned "+v.getvt());
}
} catch (IllegalStateException ise){
throw new RuntimeException("getvt() on uninitialized variant shoud have succeeded, but instead threw exception");
}
try {
v.toString();
} catch (IllegalStateException ise){
fail("toString() should never throw a runtime exception");
throw new RuntimeException("toString() should not blow up even with uninitialized Variant");
}
}
/**
*
* verify the toString() method does not do type conversion
*/
public void testToStringDoesNotConvert(){
Variant v;
v = new Variant(true);
v.toString();
if (v.getvt() != Variant.VariantBoolean){
throw new RuntimeException("toString() converted boolean to something else");
} else {
//fail("toString() correctly does not convert type");
}
if (v.getBoolean() != true){
fail("toString() converted boolean true to "+ v.getBoolean());
}
v = new Variant(false);
v.toString();
if (v.getvt() != Variant.VariantBoolean){
throw new RuntimeException("toString() converted boolean to something else");
} else {
//fail("toString() correctly does not convert type");
}
if (v.getBoolean() != false){
fail("toString() converted boolean false to "+ v.getBoolean());
}
}
public void testSafeReleaseBoolean(){
Variant v;
v = new Variant(true);
//System.out.println("Newly created Variant ("+ v.getBoolean()+") "+
// "trying to create access violation but it doesn't seem to be easy");
v.safeRelease();
try {
v.getBoolean();
fail("IllegalStateException should have been thrown when querying safeReleased object");
throw new RuntimeException("test failed");
} catch (IllegalStateException ise){
//System.out.println("IllegalStateException correctly thrown after safeRelease");
}
v = new Variant(true);
for ( int i = 0 ; i < 10; i ++){
new Variant ("xxx"+i);
new Variant(i);
new Variant ("yyy"+i);
}
ComThread.Release();
try {
v.getBoolean();
fail("IllegalStateException should have been thrown when querying ComThread.Release");
throw new RuntimeException("test failed");
} catch (IllegalStateException ise){
//System.out.println("IllegalStateException correctly thrown after ComThread.Release");
}
}
/**
* verify the constant values aren't released with safeRelease
*
*/
public void testSafeReleaseConstant(){
//System.out.println("Using Static constant Variant - should never throw access violation");
Variant.VT_TRUE.safeRelease();
if (Variant.VT_TRUE.getBoolean() != true){
fail("VT_TRUE has been broken by SafeRelease()");
throw new RuntimeException("test failed");
} else {
//System.out.println("VT_TRUE survived SafeRelease()");
}
for ( int i = 0 ; i < 10; i ++){
new Variant ("xxx"+i);
new Variant(i);
new Variant ("yyy"+i);
}
ComThread.Release();
if (Variant.VT_TRUE.getBoolean() != true){
fail("VT_TRUE has been broken by ComThread.Release()");
throw new RuntimeException("test failed");
} else {
//System.out.println("VT_TRUE survived ComThread.Release()");
}
}
/**
* this used to try and and create an access violation but that
* didn't work and now the methods on the Variant are smarter about
* working after a release
*
*/
public void testSafeReleaseString(){
String mTestString = "Guitar Hero";
Variant v = new Variant(mTestString);
//System.out.println("Newly created Variant ("+ v.getString()+") "+
// "about to safe release and then access");
v.safeRelease();
try {
v.getString();
fail("IllegalStateException should have been thrown when querying safeReleased object");
throw new RuntimeException("test failed");
} catch (IllegalStateException ise){
//System.out.println("IllegalStateException correctly thrown after safeRelease");
}
}
/**
* verifies objectIsAConstant works as expected
*
*/
public void testObjectIsAConstant(){
Variant v = new Variant("d");
if (!v.objectIsAConstant(Variant.VT_FALSE)){
fail("did not recognize VT_FALSE");
}
if (!v.objectIsAConstant(Variant.VT_TRUE)){
fail("did not recognize VT_TRUE");
}
if (!v.objectIsAConstant(Variant.VT_MISSING)){
fail("did not recognize VT_MISSING");
}
if (!v.objectIsAConstant(Variant.DEFAULT)){
fail("did not recognize DEFAULT");
}
if (v.objectIsAConstant(new Variant(true))){
fail("confused a boolean with VT_TRUE");
}
if (v.objectIsAConstant(new Variant(false))){
fail("confused a boolean with VT_FALSE");
}
}
/**
* tests put and get methods looking for obvious defects
*
*/
public void testPutsAndGets(){
Variant v = new Variant();
v.putInt((int)10);
assertEquals("int test failed", (int)10, v.getInt());
v.putShort((short)20);
assertEquals("short test failed", (short)20, v.getShort());
v.putByte((byte)30);
assertEquals("byte test failed", (byte)30, v.getByte());
v.putFloat(40);
if (v.getFloat() != 40.0){
fail("float test failed");
}
v.putDouble(50);
if (v.getDouble() != 50.0){
fail("double test failed");
}
v.putString("1234.567");
assertEquals("string test failed","1234.567", v.getString());
v.putBoolean(true);
assertEquals("failed boolean test(true)",true, v.getBoolean());
v.putBoolean(false);
assertEquals("failed boolean test(false)",false,v.getBoolean());
v.putCurrency(123456789123456789L);
assertEquals("failed currency test",123456789123456789L, v.getCurrency());
BigDecimal testDecimal = new BigDecimal("22.222");
v.putDecimal(testDecimal);
assertEquals("failed BigDecimal test", testDecimal,v.getDecimal());
Date ourDate = new Date();
v.putDate(ourDate);
Date retrievedDate = v.getJavaDate();
if (!retrievedDate.equals(ourDate)){
fail("failed java date load and unload");
}
v.putNull();
if (!v.isNull()){
fail("failed detecting set null");
}
v.putString("something other than null");
if (v.isNull()){
fail("failed null replacement with string");
}
v.putEmpty();
if (!v.isNull()){
fail("failed detecting set empty as null");
}
v.putString("something other than null");
if (v.isNull()){
fail("failed empty replacement with string as isNull");
}
Variant v2 = new Variant();
v2.putNothing();
if (v2.getvt() != Variant.VariantDispatch){
fail("putNothing was supposed to set the type to VariantDispatch");
}
if (!v2.isNull()){
fail("putNothing is supposed to cause isNull() to return true");
}
// this line blows up in the test above
if (v2.toJavaObject() == null){
fail("putNothing() followed by toJavaObject() should return a Dispatch");
}
}
/**
* Spin up a lot of threads and have them all create variants
* 3/2007 there have been several reports in multi-threaded servers that show init() failing
*
*/
public void testManyThreadedInit(){
VariantInitTestThread threads[] = new VariantInitTestThread[75];
System.out.println("Starting thread test ("+threads.length
+ " threads each creating 10000 objects)."
+ " This may take 30 seconds or more.");
for (int i = 0; i < threads.length; i++)
{
threads[i] = new VariantInitTestThread("thread-" + i, 10000);
}
for (int i = 0; i < threads.length; i++)
{
threads[i].start();
}
int numComplete = 0;
while (numComplete < threads.length){
// give the works time to work
try {
Thread.sleep(333);
} catch (InterruptedException ie){
// do nothing
}
numComplete = 0;
for ( int i = 0; i < threads.length; i++){
if (threads[i].isComplete){
numComplete++;
}
}
//System.out.print("["+numComplete+"/"+threads.length+"]");
}
System.out.println("Finished thread test");
}
/**
* a class to create variants in seperate threads
* @author joe
*
*/
class VariantInitTestThread extends Thread
{
private boolean isComplete = false;
private int initialRunSize = 0;
/**
* @param arg0
*/
public VariantInitTestThread(String newThreadName, int iStartCount)
{
super(newThreadName);
initialRunSize = iStartCount;
}
public boolean isComplete(){
return isComplete;
}
/**
* Blow out a bunch of Variants
*
* @see java.lang.Runnable#run()
*/
public void run()
{
for (int variantIndex = 0; variantIndex < initialRunSize; variantIndex ++ ){
try {
Thread.yield();
Thread.sleep(0);
} catch (InterruptedException ie){
// do nothing
}
//System.out.println(Thread.currentThread().getName());
Variant testSubject = new Variant(variantIndex);
testSubject.getvt();
testSubject.getInt();
}
isComplete = true;
}
}
}