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