#!/bin/java bsh.Interpreter

import java.awt.event.ActionListener;

source("TestHarness.bsh");

assert( this instanceof Runnable );

import bsh.Capabilities;

if ( Capabilities.canGenerateInterfaces() ) {

	assert( this instanceof bsh.XThis );

	// 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 );

} else
	warning("No proxy mechanism to test!");

complete();

