vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 28 Nov 2012 14:51:52 +0100
branchlazy
changeset 214 a0f4460130b9
parent 213 9dc53108d3df
child 215 cdd00892d06e
permissions -rw-r--r--
We can load in dependant classes
jaroslav@201
     1
/**
jaroslav@201
     2
 * Back 2 Browser Bytecode Translator
jaroslav@201
     3
 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@201
     4
 *
jaroslav@201
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@201
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@201
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@201
     8
 *
jaroslav@201
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@201
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@201
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@201
    12
 * GNU General Public License for more details.
jaroslav@201
    13
 *
jaroslav@201
    14
 * You should have received a copy of the GNU General Public License
jaroslav@201
    15
 * along with this program. Look for COPYING file in the top folder.
jaroslav@201
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
jaroslav@201
    17
 */
jaroslav@201
    18
package org.apidesign.vm4brwsr;
jaroslav@201
    19
jaroslav@201
    20
import java.io.IOException;
jaroslav@201
    21
import java.io.InputStream;
jaroslav@201
    22
import javax.script.Invocable;
jaroslav@201
    23
import javax.script.ScriptContext;
jaroslav@201
    24
import javax.script.ScriptEngine;
jaroslav@201
    25
import javax.script.ScriptException;
jaroslav@201
    26
import org.testng.annotations.BeforeClass;
jaroslav@201
    27
import static org.testng.Assert.*;
jaroslav@201
    28
import org.testng.annotations.Test;
jaroslav@201
    29
jaroslav@201
    30
/** Implements loading class by class.
jaroslav@201
    31
 *
jaroslav@201
    32
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@201
    33
 */
jaroslav@201
    34
public class VMLazyTest {
jaroslav@201
    35
jaroslav@201
    36
    
jaroslav@201
    37
    private static CharSequence codeSeq;
jaroslav@201
    38
    private static Invocable code;
jaroslav@201
    39
jaroslav@201
    40
    @BeforeClass
jaroslav@201
    41
    public void compileTheCode() throws Exception {
jaroslav@201
    42
        StringBuilder sb = new StringBuilder();
jaroslav@201
    43
        
jaroslav@201
    44
        sb.append("\nfunction test(clazz, as, method) {");
jaroslav@214
    45
        sb.append("\n  var l = new lazyVM(this);");
jaroslav@201
    46
        sb.append("\n  var c = l.loadClass(clazz, as);");
jaroslav@201
    47
        sb.append("\n  return c[method]();");
jaroslav@201
    48
        sb.append("\n}");
jaroslav@201
    49
        
jaroslav@201
    50
        
jaroslav@214
    51
        sb.append("\nfunction lazyVM(global) {");
jaroslav@201
    52
        sb.append("\n  var self = this;");
jaroslav@214
    53
        sb.append("\n  var glb = global;");
jaroslav@214
    54
        sb.append("\n  lazyVM.prototype.loadClass = function(res, name) {");
jaroslav@214
    55
        sb.append("\n    var script = org_apidesign_vm4brwsr_VMLazy(true)."
jaroslav@214
    56
            + "toJavaScriptLjava_lang_StringLjava_lang_ObjectLjava_lang_ObjectAB("
jaroslav@214
    57
            + "  glb, self,"
jaroslav@214
    58
            + "  loader.get(res + '.class')"
jaroslav@214
    59
            + ");");
jaroslav@202
    60
        sb.append("\n    try {");
jaroslav@213
    61
        sb.append("\n      new Function(script)(self, name);");
jaroslav@202
    62
        sb.append("\n    } catch (ex) {");
jaroslav@202
    63
        sb.append("\n      throw 'Cannot compile ' + res + ' error: ' + ex + ' script:\\n' + script;");
jaroslav@202
    64
        sb.append("\n    };");
jaroslav@211
    65
        sb.append("\n    return self[name](true);");
jaroslav@201
    66
        sb.append("\n  };");
jaroslav@201
    67
        sb.append("\n");
jaroslav@201
    68
        sb.append("\n}\n");
jaroslav@201
    69
        
jaroslav@201
    70
        ScriptEngine[] arr = { null };
jaroslav@201
    71
        code = StaticMethodTest.compileClass(sb, arr,
jaroslav@201
    72
            "org/apidesign/vm4brwsr/VMLazy"
jaroslav@201
    73
        );
jaroslav@201
    74
        arr[0].getContext().setAttribute("loader", new FindBytes(), ScriptContext.ENGINE_SCOPE);
jaroslav@201
    75
        codeSeq = sb;
jaroslav@201
    76
    }
jaroslav@201
    77
    
jaroslav@201
    78
    @Test public void invokeStaticMethod() throws Exception {
jaroslav@201
    79
        assertExec("Trying to get -1", "test", Double.valueOf(-1),
jaroslav@211
    80
            "org/apidesign/vm4brwsr/StaticMethod", "org_apidesign_vm4brwsr_StaticMethod", "minusOneI"
jaroslav@201
    81
        );
jaroslav@201
    82
    }
jaroslav@214
    83
jaroslav@214
    84
    @Test public void loadDependantClass() throws Exception {
jaroslav@214
    85
        assertExec("Trying to get zero", "test", Double.valueOf(0),
jaroslav@214
    86
            "org/apidesign/vm4brwsr/InstanceSub", "org_apidesign_vm4brwsr_InstanceSub", "recallDblD"
jaroslav@214
    87
        );
jaroslav@214
    88
    }
jaroslav@201
    89
jaroslav@201
    90
    private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
jaroslav@201
    91
        Object ret = null;
jaroslav@201
    92
        try {
jaroslav@201
    93
            ret = code.invokeFunction(methodName, args);
jaroslav@201
    94
        } catch (ScriptException ex) {
jaroslav@201
    95
            fail("Execution failed in\n" + StaticMethodTest.dumpJS(codeSeq), ex);
jaroslav@201
    96
        } catch (NoSuchMethodException ex) {
jaroslav@201
    97
            fail("Cannot find method in\n" + StaticMethodTest.dumpJS(codeSeq), ex);
jaroslav@201
    98
        }
jaroslav@201
    99
        if (ret == null && expRes == null) {
jaroslav@201
   100
            return;
jaroslav@201
   101
        }
jaroslav@201
   102
        if (expRes.equals(ret)) {
jaroslav@201
   103
            return;
jaroslav@201
   104
        }
jaroslav@201
   105
        assertEquals(ret, expRes, msg + "was: " + ret + "\n" + codeSeq);
jaroslav@201
   106
    }
jaroslav@201
   107
jaroslav@201
   108
    public static final class FindBytes {
jaroslav@201
   109
        public byte[] get(String name) throws IOException {
jaroslav@201
   110
            InputStream is = VMLazyTest.class.getClassLoader().getResourceAsStream(name);
jaroslav@201
   111
            if (is == null) {
jaroslav@201
   112
                throw new IOException("Can't find " + name);
jaroslav@201
   113
            }
jaroslav@201
   114
            byte[] arr = new byte[is.available()];
jaroslav@201
   115
            int len = is.read(arr);
jaroslav@201
   116
            if (len != arr.length) {
jaroslav@201
   117
                throw new IOException("Read only " + len + " wanting " + arr.length);
jaroslav@201
   118
            }
jaroslav@201
   119
            System.err.print("loader['" + name + "'] = [");
jaroslav@201
   120
            for (int i = 0; i < arr.length; i++) {
jaroslav@201
   121
                if (i > 0) {
jaroslav@201
   122
                    System.err.print(", ");
jaroslav@201
   123
                }
jaroslav@201
   124
                System.err.print(arr[i]);
jaroslav@201
   125
            }
jaroslav@201
   126
            System.err.println("]");
jaroslav@201
   127
            return arr;
jaroslav@201
   128
        }
jaroslav@201
   129
    }
jaroslav@201
   130
}