/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2014 Wisdom Framework
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.wisdom.template.thymeleaf;
import ognl.NumericTypes;
import ognl.OgnlOps;
import org.apache.commons.io.FileUtils;
import org.assertj.core.api.Assertions;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Basic OGNL tests, especially the patched part. Unlike {@link org.wisdom.template.thymeleaf.OgnlOpsTest}, this class defines the OGNLOps class so Jacoco can computes the coverage.
*/
public class OgnlOpsByReflectionTest {
private static Class clazz;
@BeforeClass
public static void prepare() throws ClassNotFoundException {
ClassLoader classLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.equals(OgnlOps.class.getName())) {
byte[] clazz;
try {
clazz = FileUtils.readFileToByteArray(new File("target/classes/ognl/OgnlOps.class"));
} catch (IOException e) {
throw new ClassNotFoundException("Cannot define the class");
}
return defineClass(OgnlOps.class.getName(), clazz, 0, clazz.length);
} else {
return OgnlOpsByReflectionTest.class.getClassLoader().loadClass(name);
}
}
};
clazz = classLoader.loadClass(OgnlOps.class.getName());
}
private Object invoke(String method, Object... args)
throws Exception {
Class[] classes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
classes[i] = Object.class;
}
return clazz.getMethod(method, classes).invoke(null, args);
}
private Object invoke(String method, Class[] classes, Object... args)
throws Exception {
return clazz.getMethod(method, classes).invoke(null, args);
}
@Test
public void testPatchedBooleanValue() throws Exception {
Assertions.assertThat((boolean) invoke("booleanValue", "true")).isTrue();
assertThat((boolean) invoke("booleanValue", "false")).isFalse();
assertThat((boolean) invoke("booleanValue", "yes")).isTrue();
assertThat((boolean) invoke("booleanValue", "no")).isFalse();
assertThat((boolean) invoke("booleanValue", "on")).isTrue();
assertThat((boolean) invoke("booleanValue", "off")).isFalse();
}
@Test
public void testNegate() throws Exception {
assertThat(invoke("negate", -1)).isEqualTo(1);
assertThat(invoke("negate", -1.0)).isEqualTo(1.0);
assertThat(invoke("negate", new BigInteger("1"))).isEqualTo(new BigInteger("-1"));
assertThat(invoke("negate", new BigDecimal(1.5))).isEqualTo(new BigDecimal(-1.5));
}
@Test
public void testRemainder() throws Exception {
assertThat(invoke("remainder", 4, 2)).isEqualTo(0);
assertThat(invoke("remainder", 4.0, 2)).isEqualTo(0.0);
assertThat(invoke("remainder", new BigInteger("4"), 2)).isEqualTo(new BigInteger("0"));
assertThat(invoke("remainder", new BigDecimal("4.0"), 2)).isEqualTo(new BigInteger("0"));
}
@Test
public void testDivide() throws Exception {
assertThat(invoke("divide", 4, 2)).isEqualTo(2);
assertThat(invoke("divide", 4.0, 2)).isEqualTo(2.0);
assertThat(invoke("divide", new BigInteger("4"), 2)).isEqualTo(new BigInteger("2"));
assertThat(invoke("divide", new BigDecimal("4.0"), 2)).isEqualTo(new BigDecimal("2.0"));
}
@Test
public void testMultiply() throws Exception {
assertThat(invoke("multiply", 4, 2)).isEqualTo(8);
assertThat(invoke("multiply", 4.0, 2)).isEqualTo(8.0);
assertThat(invoke("multiply", new BigInteger("4"), 2)).isEqualTo(new BigInteger("8"));
assertThat(invoke("multiply", new BigDecimal("4.0"), 2)).isEqualTo(new BigDecimal("8.0"));
}
@Test
public void testSubtract() throws Exception {
assertThat(invoke("subtract", 4, 2)).isEqualTo(2);
assertThat(invoke("subtract", 4.0, 2)).isEqualTo(2.0);
assertThat(invoke("subtract", new BigInteger("4"), 2)).isEqualTo(new BigInteger("2"));
assertThat(invoke("subtract", new BigDecimal("4.0"), 2)).isEqualTo(new BigDecimal("2.0"));
}
@Test
public void testAdd() throws Exception {
assertThat(invoke("add", 4, 2)).isEqualTo(6);
assertThat(invoke("add", 4.0, 2)).isEqualTo(6.0);
assertThat(invoke("add", new BigInteger("4"), 2)).isEqualTo(new BigInteger("6"));
assertThat(invoke("add", new BigDecimal("4.0"), 2)).isEqualTo(new BigDecimal("6.0"));
// The add method can also be used on String resulting in a concatenation
assertThat(invoke("add", "4", "2")).isEqualTo("42");
assertThat(invoke("add", "foo", "bar")).isEqualTo("foobar");
}
@Test
public void testShifts() throws Exception {
assertThat(invoke("shiftLeft", 30, 2)).isEqualTo(120);
assertThat(invoke("shiftLeft", new BigInteger("30"), 2)).isEqualTo(new BigInteger("120"));
assertThat(invoke("shiftRight", 30, 2)).isEqualTo(7);
assertThat(invoke("shiftRight", new BigInteger("30"), 2)).isEqualTo(new BigInteger("7"));
assertThat(invoke("unsignedShiftRight", 30, 2)).isEqualTo(7);
assertThat(invoke("unsignedShiftRight", 30l, 2)).isEqualTo(7l);
assertThat(invoke("unsignedShiftRight", new BigInteger("30"), 2)).isEqualTo(new BigInteger("7"));
}
@Test
public void testIn() throws Exception {
assertThat((boolean) invoke("in", "b", Arrays.asList("a", "b", "c"))).isTrue();
assertThat((boolean) invoke("in", "d", Arrays.asList("a", "b", "c"))).isFalse();
assertThat((boolean) invoke("in", "b", new String[]{"a", "b", "c"})).isTrue();
assertThat((boolean) invoke("in", "d", new String[]{"a", "b", "c"})).isFalse();
assertThat((boolean) invoke("in", "d", null)).isFalse();
}
@Test
public void testLessAndGreater() throws Exception {
assertThat((boolean) invoke("less", 1, 2)).isTrue();
assertThat((boolean) invoke("less", "1", "2")).isTrue();
assertThat((boolean) invoke("less", 2, 1)).isFalse();
assertThat((boolean) invoke("greater", 2, 1)).isTrue();
assertThat((boolean) invoke("greater", "2", "1")).isTrue();
}
@Test
public void testBinaryOperator() throws Exception {
assertThat(invoke("binaryAnd", "42", "8")).isEqualTo(new BigInteger("8"));
assertThat(invoke("binaryAnd", new BigInteger("42"), "8")).isEqualTo(new BigInteger("8"));
assertThat(invoke("binaryOr", "42", "8")).isEqualTo(new BigInteger("42"));
assertThat(invoke("binaryOr", new BigInteger("42"), "8")).isEqualTo(new BigInteger("42"));
assertThat(invoke("binaryXor", "42", "8")).isEqualTo(new BigInteger("34"));
assertThat(invoke("binaryXor", new BigInteger("42"), "8")).isEqualTo(new BigInteger("34"));
}
@Test
public void testNewReal() throws Exception {
Class[] classes = new Class[]{Integer.TYPE, Double.TYPE};
assertThat(invoke("newReal", classes, NumericTypes.FLOAT, 42.0)).isEqualTo(42f);
assertThat(invoke("newReal", classes, NumericTypes.DOUBLE, 42.0)).isEqualTo(42d);
}
@Test
public void testNewInteger() throws Exception {
Class[] classes = new Class[]{Integer.TYPE, Long.TYPE};
assertThat(invoke("newInteger", classes, NumericTypes.INT, 42l)).isEqualTo(42);
assertThat(invoke("newInteger", classes, NumericTypes.LONG, 42l)).isEqualTo(42l);
assertThat(invoke("newInteger", classes, NumericTypes.BYTE, 8)).isEqualTo(new Byte("8"));
assertThat(invoke("newInteger", classes, NumericTypes.SHORT, 42)).isEqualTo(new Short("42"));
// Also works with float and double, but only if there are no decimal part
assertThat(invoke("newInteger", classes, NumericTypes.FLOAT, 42)).isEqualTo(42f);
assertThat(invoke("newInteger", classes, NumericTypes.DOUBLE, 42)).isEqualTo(42d);
}
@Test
public void testConvertValue() throws Exception {
Class[] classes = new Class[]{Object.class, Class.class};
// Null value
assertThat(invoke("convertValue", classes, null, Long.TYPE)).isEqualTo(0l);
assertThat(invoke("convertValue", classes, null, String.class)).isNull();
// Primitive
assertThat(invoke("convertValue", classes, "42", Integer.class)).isEqualTo(42);
assertThat(invoke("convertValue", classes, "42", Integer.TYPE)).isEqualTo(42);
assertThat(invoke("convertValue", classes, "42", Byte.class)).isEqualTo(Byte.valueOf("42"));
assertThat(invoke("convertValue", classes, "42", Byte.TYPE)).isEqualTo(Byte.valueOf("42"));
assertThat(invoke("convertValue", classes, "42", Short.class)).isEqualTo(Short.valueOf("42"));
assertThat(invoke("convertValue", classes, "42", Short.TYPE)).isEqualTo(Short.valueOf("42"));
assertThat(invoke("convertValue", classes, String.valueOf((int) 'c'), Character.class)).isEqualTo('c');
assertThat(invoke("convertValue", classes, String.valueOf((int) 'c'), Character.TYPE)).isEqualTo('c');
assertThat(invoke("convertValue", classes, "42", Long.class)).isEqualTo(42l);
assertThat(invoke("convertValue", classes, "42", Long.TYPE)).isEqualTo(42l);
assertThat(invoke("convertValue", classes, "true", Boolean.class)).isEqualTo(true);
assertThat(invoke("convertValue", classes, "true", Boolean.TYPE)).isEqualTo(true);
assertThat(invoke("convertValue", classes, "42", Double.class)).isEqualTo(42.0);
assertThat(invoke("convertValue", classes, "42", Double.TYPE)).isEqualTo(42.0);
assertThat(invoke("convertValue", classes, "42", Float.class)).isEqualTo(42.0f);
assertThat(invoke("convertValue", classes, "42", Float.TYPE)).isEqualTo(42.0f);
// BigInteger, BigDecimal and String
assertThat(invoke("convertValue", classes, "42", BigDecimal.class)).isEqualTo(new BigDecimal("42"));
assertThat(invoke("convertValue", classes, "42", BigInteger.class)).isEqualTo(new BigInteger("42"));
assertThat(invoke("convertValue", classes, "42", String.class)).isEqualTo("42");
//Array
assertThat(invoke("convertValue", classes, new Object[]{1, 2, 3}, (new int[0]).getClass())).isNotNull();
}
@Test
public void testBitNegate() throws Exception {
assertThat(invoke("bitNegate", "42")).isEqualTo(new BigInteger("-43"));
assertThat(invoke("bitNegate", new BigInteger("42"))).isEqualTo(new BigInteger("-43"));
assertThat(invoke("bitNegate", new BigDecimal("42"))).isEqualTo(new BigInteger("-43"));
}
}