package org.develnext.jphp.core.compiler.jvm; import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.junit.runners.MethodSorters; import php.runtime.memory.*; import php.runtime.Memory; @RunWith(JUnit4.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class SimpleExpressionTest extends JvmCompilerCase { @Test public void testReturn(){ Memory memory = run("return;", false); Assert.assertTrue(memory instanceof NullMemory); } @Test public void testSimple(){ Memory memory = run("1"); Assert.assertEquals(1, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); memory = run("1.2"); Assert.assertEquals(1.2, memory.toDouble(), 0.00001); memory = run("'foobar'"); Assert.assertEquals("foobar", memory.toString()); memory = run("false"); Assert.assertTrue(memory instanceof FalseMemory); memory = run("true"); Assert.assertTrue(memory instanceof TrueMemory); memory = run("null"); Assert.assertTrue(memory instanceof NullMemory); } @Test public void testArithmetic(){ Memory memory = run("1 + 2"); Assert.assertEquals(3, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); memory = run("1 - 2"); Assert.assertEquals(-1, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); memory = run("-1 - 2"); Assert.assertEquals(-3, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); memory = run("-1 * 2"); Assert.assertEquals(-2, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); memory = run("-1 / 2"); Assert.assertEquals(-0.5, memory.toDouble(), 0.0000001); Assert.assertTrue(memory instanceof DoubleMemory); memory = run("5 % 2"); Assert.assertEquals(1, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); } @Test public void testConcat(){ Memory memory = run("'foo' . 'bar'"); Assert.assertEquals("foobar", memory.toString()); memory = run("1 . 'bar'"); Assert.assertEquals("1bar", memory.toString()); memory = run("false . 'bar'"); Assert.assertEquals("bar", memory.toString()); memory = run("1.0 . 'bar'"); Assert.assertEquals("1bar", memory.toString()); memory = run("$x = 'foo';\n" + "return 'bar' . (string)$x;", false); Assert.assertEquals("barfoo", memory.toString()); } @Test public void testLocalVariable(){ Memory memory = run("$x"); Assert.assertTrue(memory instanceof NullMemory); } @Test public void testNot(){ Memory memory = run("!true"); Assert.assertEquals(false, memory.toBoolean()); memory = runDynamic("!$x"); Assert.assertEquals(true, memory.toBoolean()); } @Test public void testAssign(){ Memory memory = run("$x = 20"); Assert.assertEquals(20, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); } @Test public void testAssignVariable(){ Memory memory = run("$x = 20; return $x", false); Assert.assertEquals(20, memory.toLong()); Assert.assertTrue(memory instanceof LongMemory); } @Test public void testAssignConcat(){ Memory memory = run("$x = 'foo'; $x .= 'bar'; return $x", false); Assert.assertEquals("foobar", memory.toString()); } @Test public void testAssignPlus(){ Memory memory = run("$x = 10; $x += 2; return $x", false); Assert.assertEquals(12, memory.toLong()); } @Test public void testAssignMinus(){ Memory memory = run("$x = 10; $x -= 2; return $x", false); Assert.assertEquals(8, memory.toLong()); } @Test public void testAssignMul(){ Memory memory = run("$x = 10; $x *= 2; return $x", false); Assert.assertEquals(20, memory.toLong()); } @Test public void testAssignDiv(){ Memory memory = run("$x = 10; $x /= 2; return $x", false); Assert.assertEquals(5, memory.toLong()); } @Test public void testAssignMod(){ Memory memory = run("$x = 10; $x %= 3; return $x", false); Assert.assertEquals(1, memory.toLong()); } @Test public void testOr(){ Memory memory = runDynamic("$x || true"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("$x or true"); Assert.assertEquals(true, memory.toBoolean()); } @Test public void testAnd(){ Memory memory = runDynamic("$x && true"); Assert.assertEquals(false, memory.toBoolean()); memory = runDynamic("$x and true"); Assert.assertEquals(false, memory.toBoolean()); } @Test public void testAndOrComplex(){ Memory memory = runDynamic("$x || (!$y && !false || true)"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("$x or (!$y and !false)"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("!$x && ($y || true)"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("!$x and ($y or true)"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("!($x && $y) && true || $z"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("$x || !$y && true"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("$x || (!$y && !null && 100500)"); Assert.assertEquals(true, memory.toBoolean()); memory = runDynamic("$z = $x || 22; return $z", false); Assert.assertEquals(Memory.TRUE, memory.toValue()); } @Test public void testMathComplex(){ Memory memory = runDynamic("3 + $x * 4"); Assert.assertEquals(3, memory.toLong()); memory = runDynamic("(3 + $x * 4) / 2"); Assert.assertEquals(1.5, memory.toDouble(), 0.000001); memory = runDynamic("$y = 2; return (7 + $x * 4) / $y;", false); Assert.assertEquals(3.5, memory.toDouble(), 0.000001); memory = runDynamic("$y = 2; return (8 + $x * 4) / $y * 2;", false); Assert.assertEquals(8, memory.toLong()); Assert.assertEquals(Memory.Type.INT, memory.type); } @Test public void testBitwise() { Memory memory = runDynamic("0x0f & ~0xf0"); Assert.assertEquals(15, memory.toLong()); } @Test public void testCallNativeFunc(){ Memory memory = runDynamic("$i = 1; return cos($i);", false); Assert.assertTrue(memory.toDouble() > 0.54); } @Test public void testArrays(){ Memory memory = runDynamic("array(1, 2, 3)"); Assert.assertTrue(memory.isArray()); Assert.assertEquals(1, memory.valueOfIndex(0).toLong()); Assert.assertEquals(2, memory.valueOfIndex(1).toLong()); Assert.assertEquals(3, memory.valueOfIndex(2).toLong()); Assert.assertEquals(3, ((ArrayMemory)memory).size()); memory = runDynamic("array('x' => 20, 'y' => 30)"); Assert.assertEquals(20, memory.valueOfIndex("x").toLong()); Assert.assertEquals(30, memory.valueOfIndex("y").toLong()); Assert.assertEquals(2, ((ArrayMemory)memory).size()); memory = runDynamic("$x['x'] = 30; return $x;", false); Assert.assertEquals(30, memory.valueOfIndex("x").toLong()); Assert.assertEquals(1, memory.toValue(ArrayMemory.class).size()); memory = runDynamic("$x[] = 30; return $x;", false); Assert.assertEquals(30, memory.valueOfIndex(0).toLong()); Assert.assertEquals(1, memory.toValue(ArrayMemory.class).size()); memory = runDynamic("array(1 => 'foobar', 30, 'x' => true, 100)"); Assert.assertTrue(memory.isArray()); Assert.assertEquals("foobar", memory.valueOfIndex(1).toString()); Assert.assertEquals(30, memory.valueOfIndex(2).toLong()); Assert.assertEquals(100, memory.valueOfIndex(3).toLong()); Assert.assertEquals(true, memory.valueOfIndex("x").toBoolean()); Assert.assertEquals(4, memory.toValue(ArrayMemory.class).size()); // test short syntax memory = runDynamic("$arr = [1 => 'foobar', 30, 'x' => true, 100]; return $arr;", false); Assert.assertTrue(memory.isArray()); Assert.assertEquals("foobar", memory.valueOfIndex(1).toString()); Assert.assertEquals(30, memory.valueOfIndex(2).toLong()); Assert.assertEquals(100, memory.valueOfIndex(3).toLong()); Assert.assertEquals(true, memory.valueOfIndex("x").toBoolean()); Assert.assertEquals(4, memory.toValue(ArrayMemory.class).size()); memory = runDynamic("[[100, 200], [500, 600]]"); Assert.assertTrue(memory.isArray()); Assert.assertEquals(2, memory.toValue(ArrayMemory.class).size()); Assert.assertTrue(memory.valueOfIndex(0).isArray()); Assert.assertEquals(2, memory.valueOfIndex(0).toValue(ArrayMemory.class).size()); Assert.assertEquals(2, memory.valueOfIndex(1).toValue(ArrayMemory.class).size()); // test logic and array memory = runDynamic("array(1 && 1, 2);"); Assert.assertTrue(memory.isArray()); Assert.assertEquals(2, memory.toValue(ArrayMemory.class).size()); } @Test public void testReferences(){ Memory memory; memory = run("$x = 40; $y =& $x; $y = 10; return $x;", false); Assert.assertEquals(10, memory.toLong()); memory = runDynamic("$x = 40; $y =& $x; $y = 10; return $x;", false); Assert.assertEquals(10, memory.toLong()); memory = runDynamic("$x = array(20, 40); $y =& $x[0]; $y = 40; return $x;", false); Assert.assertTrue(memory.isArray()); Assert.assertEquals(40, memory.valueOfIndex(0).toLong()); Assert.assertEquals(40, memory.valueOfIndex(1).toLong()); memory = run("$x = array(20, 40); $y =& $x[0]; $y = 40; return $x;", false); Assert.assertTrue(memory.isArray()); Assert.assertEquals(40, memory.valueOfIndex(0).toLong()); Assert.assertEquals(40, memory.valueOfIndex(1).toLong()); memory = runDynamic("$y =& $x['z']; $x['z'] = 40; return $y;", false); Assert.assertEquals(40, memory.toLong()); memory = run("$y =& $x['z']; $x['z'] = 40; return $y;", false); Assert.assertEquals(40, memory.toLong()); } @Test public void testGlobals(){ Memory memory; memory = runDynamic("$x = 100500; function test() { global $x; return $x; } return test();", false); Assert.assertEquals(100500, memory.toLong()); memory = runDynamic("function test() { global $y; $y = 220; } test(); return $y;", false); Assert.assertEquals(220, memory.toLong()); } @Test public void testStatics(){ Memory memory; memory = runDynamic("function test() { static $i = 3; $i++; return $i; } test(); return test();", false); Assert.assertEquals(5, memory.toLong()); memory = runDynamic("function test() { static $i; $i++; return $i; } test(); return test();", false); Assert.assertEquals(2, memory.toLong()); } @Test public void testStringBuilder(){ Memory memory; memory = runDynamic("$x = 100500; return \"foo $x bar\";", false); Assert.assertEquals("foo 100500 bar", memory.toString()); } @Test public void testStringIdentical() { Memory memory = runDynamic("$a = 'foo';\n" + "return ($a === 'foo' ? 1 : 0) . ('foo' === $a ? 1 : 0);", false); Assert.assertEquals("11", memory.toString()); } @Test public void testStringCharAt() { Memory memory; memory = runDynamic("$x = 'foobar'; return $x[3];", false); Assert.assertEquals("b", memory.toString()); memory = runDynamic("$x = 'foobar'; $x[3] = 'B'; return $x;", false); Assert.assertEquals("fooBar", memory.toString()); memory = runDynamic("$x = 'foobar'; $x[6] = '1'; return $x;", false); Assert.assertEquals("foobar1", memory.toString()); memory = runDynamic("$x = 'foobar'; $x[7] = '1'; $x[7] = '2'; return $x;", false); Assert.assertEquals("foobar\32" + "2", memory.toString()); memory = runDynamic("$x = 'foobar'; $x[3] = ''; return $x;", false); Assert.assertEquals("foo"+ '\0' + "ar", memory.toString()); } @Test public void testBinaryIntegers() { Memory memory = runDynamic("0b11111111"); Assert.assertEquals(255, memory.toLong()); Assert.assertEquals(Memory.Type.INT, memory.type); } @Test public void testOctalIntegers() { Memory memory = runDynamic("010"); Assert.assertEquals(8, memory.toLong()); Assert.assertEquals(Memory.Type.INT, memory.type); } @Test public void testUnaryPlusMinus() { Memory memory; memory = runDynamic("+ 1"); Assert.assertEquals(1, memory.toLong()); memory = runDynamic("- 1"); Assert.assertEquals(-1, memory.toLong()); memory = runDynamic("+ 0x01"); Assert.assertEquals(1, memory.toLong()); memory = runDynamic("- 0x01"); Assert.assertEquals(-1, memory.toLong()); memory = runDynamic("+ 0b01"); Assert.assertEquals(1, memory.toLong()); memory = runDynamic("- 0b01"); Assert.assertEquals(-1, memory.toLong()); memory = runDynamic("+ 010"); Assert.assertEquals(8, memory.toLong()); memory = runDynamic("- 010"); Assert.assertEquals(-8, memory.toLong()); } @Test public void testBug119() { Memory r = runDynamic("$val = 3; $t = '2'; return '1' . $t . (int)$val;", false); Assert.assertEquals("123", r.toString()); } }