vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 11 Dec 2012 09:36:44 +0100
branchlazyvm
changeset 298 885acca2fa0b
parent 276 aeb9fe11cd60
child 306 f36b3c273de6
permissions -rw-r--r--
Creating Bck2Brwsr entrypoint to for those who wish to generate their JavaScript based Java VM
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.vm4brwsr;
    19 
    20 import java.io.File;
    21 import java.io.FileWriter;
    22 import java.io.IOException;
    23 import java.io.InputStream;
    24 import java.net.URL;
    25 import java.util.Enumeration;
    26 import javax.script.Invocable;
    27 import javax.script.ScriptEngine;
    28 import javax.script.ScriptEngineManager;
    29 import javax.script.ScriptException;
    30 import static org.testng.Assert.*;
    31 import org.testng.annotations.BeforeClass;
    32 import org.testng.annotations.Test;
    33 
    34 /** Checks the basic behavior of the translator.
    35  *
    36  * @author Jaroslav Tulach <jtulach@netbeans.org>
    37  */
    38 public class StaticMethodTest {
    39     @Test public void threePlusFour() throws Exception {
    40         assertExec(
    41             "Should be seven", 
    42             StaticMethod.class, "sum__III", 
    43             Double.valueOf(7), 
    44             3, 4
    45         );
    46     }
    47 
    48     @Test public void checkReallyInitializedValues() throws Exception {
    49         assertExec(
    50             "Return true", 
    51             StaticMethod.class, "isNull__Z", 
    52             Double.valueOf(1)
    53         );
    54     }
    55 
    56     @Test public void powerOfThree() throws Exception {
    57         assertExec(
    58             "Should be nine", 
    59             StaticMethod.class, "power__FF", 
    60             Double.valueOf(9),
    61             3.0f
    62         );
    63     }
    64 
    65     @Test public void minusOne() throws Exception {
    66         assertExec(
    67             "Should be minus one", 
    68             StaticMethod.class, "minusOne__I", 
    69             Double.valueOf(-1)
    70         );
    71     }
    72 
    73     @Test public void doubleWithoutLong() throws Exception {
    74         assertExec(
    75             "Should be two",
    76             StaticMethod.class, "minus__DDJ", 
    77             Double.valueOf(2),
    78             3.0d, 1l
    79         );
    80     }
    81 
    82     @Test public void divAndRound() throws Exception {
    83         assertExec(
    84             "Should be rounded to one",
    85             StaticMethod.class, "div__IBD", 
    86             Double.valueOf(1),
    87             3, 3.75
    88         );
    89     }
    90     @Test public void mixedMethodFourParams() throws Exception {
    91         assertExec(
    92             "Should be two",
    93             StaticMethod.class, "mix__IIJBD", 
    94             Double.valueOf(20),
    95             2, 10l, 5, 2.0
    96         );
    97     }
    98     @Test public void factRec() throws Exception {
    99         assertExec(
   100             "Factorial of 5 is 120",
   101             StaticMethod.class, "factRec__JI", 
   102             Double.valueOf(120),
   103             5
   104         );
   105     }
   106     @Test public void factIter() throws Exception {
   107         assertExec(
   108             "Factorial of 5 is 120",
   109             StaticMethod.class, "factIter__JI", 
   110             Double.valueOf(120),
   111             5
   112         );
   113     }
   114     
   115     @Test public void xor() throws Exception {
   116         assertExec(
   117             "Xor is 4",
   118             StaticMethod.class, "xor__JIJ",
   119             Double.valueOf(4),
   120             7,
   121             3
   122         );
   123     }
   124     
   125     @Test public void or() throws Exception {
   126         assertExec(
   127             "Or will be 7",
   128             StaticMethod.class, "orOrAnd__JZII",
   129             Double.valueOf(7),
   130             true,
   131             4,
   132             3
   133         );
   134     }
   135     @Test public void nullCheck() throws Exception {
   136         assertExec(
   137             "Returns nothing",
   138             StaticMethod.class, "none__Ljava_lang_Object_2II",
   139             null, 1, 3
   140         );
   141     }
   142     @Test public void and() throws Exception {
   143         assertExec(
   144             "And will be 3",
   145             StaticMethod.class, "orOrAnd__JZII",
   146             Double.valueOf(3),
   147             false,
   148             7,
   149             3
   150         );
   151     }
   152     @Test public void inc4() throws Exception {
   153         assertExec(
   154             "It will be 4",
   155             StaticMethod.class, "inc4__I",
   156             Double.valueOf(4)
   157         );
   158     }
   159     
   160     @Test public void shiftLeftInJava() throws Exception {
   161         int res = StaticMethod.shiftLeft(1, 8);
   162         assertEquals(res, 256);
   163     }
   164 
   165     @Test public void shiftLeftInJS() throws Exception {
   166         assertExec(
   167             "Setting 9th bit",
   168             StaticMethod.class, "shiftLeft__III",
   169             Double.valueOf(256),
   170             1, 8
   171         );
   172     }
   173 
   174     @Test public void shiftRightInJava() throws Exception {
   175         int res = StaticMethod.shiftArithmRight(-8, 3, true);
   176         assertEquals(res, -1);
   177     }
   178 
   179     @Test public void shiftRightInJS() throws Exception {
   180         assertExec(
   181             "Get -1",
   182             StaticMethod.class, "shiftArithmRight__IIIZ",
   183             Double.valueOf(-1),
   184             -8, 3, true
   185         );
   186     }
   187     @Test public void unsignedShiftRightInJava() throws Exception {
   188         int res = StaticMethod.shiftArithmRight(8, 3, false);
   189         assertEquals(res, 1);
   190     }
   191 
   192     @Test public void unsignedShiftRightInJS() throws Exception {
   193         assertExec(
   194             "Get -1",
   195             StaticMethod.class, "shiftArithmRight__IIIZ",
   196             Double.valueOf(1),
   197             8, 3, false
   198         );
   199     }
   200     
   201     @Test public void javaScriptBody() throws Exception {
   202         assertExec(
   203             "JavaScript string",
   204             StaticMethod.class, "i2s__Ljava_lang_String_2II",
   205             "333",
   206             330, 3
   207         );
   208     }
   209     
   210     @Test public void switchJarda() throws Exception {
   211         assertExec(
   212             "The expected value",
   213             StaticMethod.class, "swtch__Ljava_lang_String_2I",
   214             "Jarda",
   215             0
   216         );
   217     }
   218     
   219     @Test public void switchDarda() throws Exception {
   220         assertExec(
   221             "The expected value",
   222             StaticMethod.class, "swtch__Ljava_lang_String_2I",
   223             "Darda",
   224             1
   225         );
   226     }
   227     @Test public void switchParda() throws Exception {
   228         assertExec(
   229             "The expected value",
   230             StaticMethod.class, "swtch2__Ljava_lang_String_2I",
   231             "Parda",
   232             22
   233         );
   234     }
   235     @Test public void switchMarda() throws Exception {
   236         assertExec(
   237             "The expected value",
   238             StaticMethod.class, "swtch__Ljava_lang_String_2I",
   239             "Marda",
   240             -433
   241         );
   242     }
   243     
   244     private static CharSequence codeSeq;
   245     private static Invocable code;
   246     
   247     @BeforeClass 
   248     public void compileTheCode() throws Exception {
   249         StringBuilder sb = new StringBuilder();
   250         code = compileClass(sb, "org/apidesign/vm4brwsr/StaticMethod");
   251         codeSeq = sb;
   252     }
   253     
   254     
   255     private static void assertExec(
   256         String msg, Class clazz, String method, 
   257         Object expRes, Object... args
   258     ) throws Exception {
   259         assertExec(code, codeSeq, msg, clazz, method, expRes, args);
   260     }
   261     static void assertExec(
   262         Invocable toRun, CharSequence theCode,
   263         String msg, Class clazz, String method, 
   264         Object expRes, Object... args
   265     ) throws Exception {
   266         Object ret = null;
   267         try {
   268             ret = toRun.invokeFunction("bck2brwsr");
   269             ret = toRun.invokeMethod(ret, "loadClass", clazz.getName());
   270             ret = toRun.invokeMethod(ret, method, args);
   271         } catch (ScriptException ex) {
   272             fail("Execution failed in\n" + dumpJS(theCode), ex);
   273         } catch (NoSuchMethodException ex) {
   274             fail("Cannot find method in\n" + dumpJS(theCode), ex);
   275         }
   276         if (ret == null && expRes == null) {
   277             return;
   278         }
   279         if (expRes != null && expRes.equals(ret)) {
   280             return;
   281         }
   282         assertEquals(ret, expRes, msg + "was: " + ret + "\n" + dumpJS(theCode));
   283         
   284     }
   285 
   286     static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
   287         return compileClass(sb, null, names);
   288     }
   289     static Invocable compileClass(
   290         StringBuilder sb, ScriptEngine[] eng, String... names
   291     ) throws ScriptException, IOException {
   292         if (sb == null) {
   293             sb = new StringBuilder();
   294         }
   295         Bck2Brwsr.generate(sb, new EmulationResources(), names);
   296         ScriptEngineManager sem = new ScriptEngineManager();
   297         ScriptEngine js = sem.getEngineByExtension("js");
   298         if (eng != null) {
   299             eng[0] = js;
   300         }
   301         try {
   302             Object res = js.eval(sb.toString());
   303             assertTrue(js instanceof Invocable, "It is invocable object: " + res);
   304             return (Invocable)js;
   305         } catch (Exception ex) {
   306             if (sb.length() > 2000) {
   307                 sb = dumpJS(sb);
   308             }
   309             fail("Could not evaluate:\n" + sb, ex);
   310             return null;
   311         }
   312     }
   313     static StringBuilder dumpJS(CharSequence sb) throws IOException {
   314         File f = File.createTempFile("execution", ".js");
   315         FileWriter w = new FileWriter(f);
   316         w.append(sb);
   317         w.close();
   318         return new StringBuilder(f.getPath());
   319     }
   320     private static class EmulationResources implements Bck2Brwsr.Resources {
   321         @Override
   322         public InputStream get(String name) throws IOException {
   323             Enumeration<URL> en = StaticMethodTest.class.getClassLoader().getResources(name);
   324             URL u = null;
   325             while (en.hasMoreElements()) {
   326                 u = en.nextElement();
   327             }
   328             if (u == null) {
   329                 throw new IOException("Can't find " + name);
   330             }
   331             if (u.toExternalForm().contains("rt.jar!")) {
   332                 throw new IOException("No emulation for " + u);
   333             }
   334             return u.openStream();
   335         }
   336     }
   337 }