package bsh;


import static javax.script.ScriptContext.ENGINE_SCOPE;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;

public class TestBshScriptEngine
{
    public static void main( String [] args )
        throws ScriptException, NoSuchMethodException, IOException
    {
        ScriptEngineManager manager =
            new ScriptEngineManager( bsh.Interpreter.class.getClassLoader() );

        ScriptEngine engine = manager.getEngineByName( "beanshell" );
        assertTrue( engine != null );

        // basic eval
        int i = (Integer)engine.eval("2*2");
        assert( i == 4 );

        // set a variable
        engine.put( "foo", 42 );
        assertTrue( (Integer)engine.get("foo") == 42 );

        // bsh primitives stay primitive internally
        engine.eval( "int fooInt=42" );
        assertTrue( (Integer)engine.get("foo") == 42 );
        assertTrue( engine.eval("fooInt.getClass()") == bsh.Primitive.class );
        assertTrue( engine.getContext().getAttribute( "fooInt", ENGINE_SCOPE )
            instanceof Integer );

        // Variables visible through bindings in both directions?
        Bindings engineScope = engine.getBindings( ENGINE_SCOPE );
        Bindings engineScope2 = engine.getContext().getBindings( ENGINE_SCOPE );
        assertTrue( engineScope == engineScope2 );
        assertTrue( engineScope.get("foo") instanceof Integer );
        engineScope.put("bar", "gee");
        // get() and eval() for us should be equivalent in this case
        assertTrue( engine.get("bar").equals("gee") );
        assertTrue( engine.eval("bar").equals("gee") );

        // install and invoke a method
        engine.eval("foo() { return foo+1; }");
        // invoke a method
        Invocable invocable = (Invocable) engine;
        int foo = (Integer)invocable.invokeFunction( "foo" );
        assertTrue( foo == 43 );

        // get interface
        engine.eval("flag=false; run() { flag=true; }");
        assertTrue( (Boolean)engine.get("flag") == false );
        assertTrue( (Boolean)engine.get("flag_nonexistent") == null );
        Runnable runnable = (Runnable)invocable.getInterface( Runnable.class );
        runnable.run();
        assertTrue( (Boolean)engine.get("flag") == true );

        // get interface from scripted object
        engine.eval(
            "flag2=false; myObj() { run() { flag2=true; } return this; }");
        assertTrue( (Boolean)engine.get("flag2") == false );
        Object scriptedObject = invocable.invokeFunction("myObj");
        assertTrue( scriptedObject instanceof bsh.This );
        runnable =
            (Runnable)invocable.getInterface( scriptedObject, Runnable.class );
        runnable.run();
        assertTrue( (Boolean)engine.get("flag2") == true );

        // Run with alternate bindings
        assertTrue( (Boolean)engine.get("flag") == true );
        assertTrue( (Integer)engine.get("foo") ==42 );
        Bindings newEngineScope = new SimpleBindings();
        engine.eval( "flag=false; foo=33;", newEngineScope );
        assertTrue( (Boolean)newEngineScope.get("flag") == false );
        assertTrue( (Integer)newEngineScope.get("foo") == 33 );
        // These are unchanged in default context
        assertTrue( (Boolean)engine.get("flag") == true );
        assertTrue( (Integer)engine.get("foo") ==42 );

        // Try redirecting output
        System.out.println( "Before redirect, stdout..." );
        String fname = "testBshScriptEngine.out";
        String outString = "Data 1 2 3.";
        Writer fout = new FileWriter( fname );
        engine.getContext().setWriter( fout );
        engine.put( "outString", outString );
        engine.eval("print(outString)");
        BufferedReader bin = new BufferedReader( new FileReader( fname ) );
        String line = bin.readLine();
        assertTrue( line.equals( outString ));
        new File(fname).delete();

        // compile
        // ...

        // Add a new scope dynamically?

    }

    static void assertTrue( boolean cond )
    {
        if ( cond )
            System.out.println( "Passed..." );
        else
            throw new Error( "assert failed..." );
    }
}

@@ -62,16 +62,59 @@
 E_SCOPE;
+%0Aimport static org.junit.Assert.assertTrue;
 %0A%0Aimport
@@ -217,36 +217,8 @@
 er;%0A
-import java.io.IOException;%0A
 impo
@@ -377,45 +377,8 @@
 er;%0A
-import javax.script.ScriptException;%0A
 impo
@@ -410,16 +410,40 @@
 dings;%0A%0A
+import org.junit.Test;%0A%0A
 public c
@@ -469,16 +469,26 @@
 ngine%0A%7B%0A
+    @Test%0A
     publ
@@ -494,113 +494,55 @@
 lic 
-static void main( String %5B%5D args )%0A        throws ScriptException, NoSuchMethodException, IOException%0A   
+void test_bsh_script_engine( ) throws Throwable
  %7B%0A 
@@ -3624,68 +3624,8 @@
 put%0A
-        System.out.println( %22Before redirect, stdout...%22 );%0A
     
@@ -4174,194 +4174,7 @@
    %7D
-%0A%0A    static void assertTrue( boolean cond )%0A    %7B%0A        if ( cond )%0A            System.out.println( %22Passed...%22 );%0A        else%0A            throw new Error( %22assert failed...%22 );%0A    %7D
 %0A%7D%0A

Convert TestBshScriptEngine to junit test.