package com.kkey;

import org.junit.Test;

import javax.script.*;

import static org.junit.Assert.assertEquals;

/**
 * Unit test for simple App.
 */
public class AppTest {
    public static final int COUNTER = 10000;
    public static String SCRIPT = "class A{\n" +
            "static arr = new String[1000]; \n" +
            "def do1() { %s }\n" +
            "}\n" +
            "\n" +
            "class C {} \n" +
            "class D {} \n" +
            "class E {} \n" +
            "class F {} \n" +
            "class G {} \n" +
            "class H {} \n" +
            "class H1 {static arr = new String[1000];} \n" +
            "new C() \n" +
            "new D() \n" +
            "new E() \n" +
            "new F() \n" +
            "new G() \n" +
            "new H() \n" +
            "new H1() \n" +
            "return new A().do1()\n";


    @Test
    public void testSimple() {
        ScriptExecutor scriptExecutorJSR223 = getScriptExecutor();

        String script = String.format(SCRIPT, "1");
        int result = 0;
        for (int i = 0; i < COUNTER; i++) {

            result += scriptExecutorJSR223.<Integer>executeScript(script);
        }

        assertEquals(COUNTER, result);
    }

    @Test
    public void testWithConcat() {
        ScriptExecutor scriptExecutorJSR223 = getScriptExecutor();

        int result = 0;
        for (int i = 0; i < COUNTER; i++) {

            result += scriptExecutorJSR223.<Integer>executeScript(String.format(SCRIPT, "1"));
        }

        assertEquals(COUNTER, result);
    }

    /**
     * Here we generate a new unique String every time
     */
    @Test
    public void testWithConcatNewString() {
        ScriptExecutor scriptExecutorJSR223 = getScriptExecutor();

        int result = 0;
        for (int i = 0; i < COUNTER; i++) {
            String header = "/* " + i + " */\n";
            result += scriptExecutorJSR223.<Integer>executeScript(header + String.format(SCRIPT, "1"));
        }

        assertEquals(COUNTER, result);
    }

    @Test
    public void testCompileOnly() throws ScriptException {
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine groovy = scriptEngineManager.getEngineByName("groovy");

        String script = String.format(SCRIPT, "1");
        for (int i = 0; i < COUNTER; i++) {
            String header = "/* " + i + " */\n";
            CompiledScript compile = ((Compilable) groovy).compile(header + script);
            if (compile.toString().equals("aaa")){
                throw new RuntimeException("Cannot be");
            }
        }
    }

    private ScriptExecutor getScriptExecutor() {
//        return new ScriptExecutorJSR223();
        return new ScriptExecutorDirect();
//        return new ScriptCreateEveryTime();
    }
}

@@ -211,16 +211,18 @@
  10000;%0A
+%0A%0A
     publ
@@ -853,24 +853,752 @@
 do1()%5Cn%22;%0A%0A%0A
+    public static String SCRIPT_2 = %22%22 +%0A            %22import com.kkey.AccessTo%5Cn%22 +%0A            %22class A%7B%5Cn%22 +%0A            %22static arr = new String%5B1000%5D; %5Cn%22 +%0A            %22def do1() %7B %25s %7D%5Cn%22 +%0A            %22%7D%5Cn%22 +%0A            %22%5Cn%22 +%0A            %22class C %7B%7D %5Cn%22 +%0A            %22class D %7B%7D %5Cn%22 +%0A            %22class E %7B%7D %5Cn%22 +%0A            %22class F %7B%7D %5Cn%22 +%0A            %22class G %7B%7D %5Cn%22 +%0A            %22class H %7B%7D %5Cn%22 +%0A            %22class H1 %7Bstatic arr = new String%5B1000%5D;%7D %5Cn%22 +%0A            %22new C() %5Cn%22 +%0A            %22new D() %5Cn%22 +%0A            %22new E() %5Cn%22 +%0A            %22new F() %5Cn%22 +%0A            %22new G() %5Cn%22 +%0A            %22new H() %5Cn%22 +%0A            %22new H1() %5Cn%22 +%0A            %22return new A().do1() + new AccessTo().get()%5Cn%22;%0A%0A
     @Test%0A  
@@ -3338,23 +3338,625 @@
       %7D%0A
-
     %7D%0A%0A
+    @Test%0A    public void testCompileOnly_for2() throws ScriptException %7B%0A        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();%0A        ScriptEngine groovy = scriptEngineManager.getEngineByName(%22groovy%22);%0A%0A        String script = String.format(SCRIPT_2, %221%22);%0A        for (int i = 0; i %3C COUNTER; i++) %7B%0A            String header = %22/* %22 + i + %22 */%5Cn%22;%0A            CompiledScript compile = ((Compilable) groovy).compile(header + script);%0A            if (compile.toString().equals(%22aaa%22))%7B%0A                throw new RuntimeException(%22Cannot be%22);%0A            %7D%0A        %7D%0A    %7D%0A%0A%0A%0A
     priv

add test