#!/bin/java bsh.Interpreter

import java.awt.event.ActionListener;

source("TestHarness.bsh");

assert( this instanceof Runnable );


// Explicit cast
assert( ((ActionListener)this) instanceof ActionListener );

// Automatic cast
ActionListener al = object();
assert( al instanceof ActionListener );

// Try out the basic interface test classes
InterfaceConsumer consumer = new InterfaceConsumer();
Interface impl1 = new InterfaceImpl();
impl2 = new InterfaceImpl();
assert( consumer.consumeInterface( impl1 ) );
assert( consumer.consumeInterface( impl2 ) );
int i = impl1.getPrimitiveInt();
Integer i2 = impl1.getInteger();
assert( impl1.getNull() == null );

// make a scripted interface
Interface si1 = new Interface() {
	String getString() { return "bar"; }
	Integer getInteger() { return new Integer(99); }
	int getPrimitiveInt() { return 42; }
	boolean getPrimitiveBool() { return false; }
	Object getNull() { return null; }
};
	
// validate that the scripted interface works from the script
String s = si1.getString();
Integer i2 = si1.getInteger();
int i = si1.getPrimitiveInt();
boolean b = si1.getPrimitiveBool();
assert( si1.getNull() == null );

// here's the real test
// validate that the scripted interface works from java
assert( consumer.consumeInterface( si1 ) );

// make a bogus interface - lacking impl
Interface si2 = new Interface() { };
assert( isEvalError( "consumer.consumeInterface( si2 )") );
assert( isEvalError( "si2.getString()" ) );

// proxy interfaces implement the object protocol
Runnable r1 = new Runnable() { };
String s = r1.toString();
int i = r1.hashCode();
assert( r1.equals( r1 ) );
assert( !r1.equals( "foo" ) );

// auto casting in method selection
// implement this stuff directly
String getString() { return "bar"; }
Integer getInteger() { return new Integer(99); }
int getPrimitiveInt() { return 42; }
boolean getPrimitiveBool() { return false; }
Object getNull() { return null; }
consumer.consumeInterface(this);

// validate that proxy objec caching is happening
assert( this == this );
this1 = (Interface)this;
this2 = (Interface)this;
assert( this1 == this2 );
this1 = this.getInterface( Interface.class );
this2 = this.getInterface( Interface.class );
assert( this1 == this2 );
this1 = this.getInterface( 
	new Class[] { Interface.class, java.util.EventListener.class } );
this2 = this.getInterface( 
	new Class[] { Interface.class, java.util.EventListener.class } );
assert( this1 == this2 );


complete();
