http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java new file mode 100644 index 0000000..4306a50 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.util.Collections; +import java.util.Date; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.model.TemplateHashModel; +import org.apache.freemarker.core.model.TemplateMethodModelEx; +import org.apache.freemarker.core.model.TemplateModelException; +import org.apache.freemarker.core.model.TemplateScalarModel; +import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat; +import org.apache.freemarker.core.outputformat.impl.TemplateHTMLOutputModel; +import org.junit.Test; + +public class ErrorMessagesTest { + + @Test + public void getterMessage() throws TemplateModelException { + DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build(); + TemplateHashModel thm= (TemplateHashModel) ow.wrap(new TestBean()); + + try { + thm.get("foo"); + } catch (TemplateModelException e) { + e.printStackTrace(); + final String msg = e.getMessage(); + assertThat(msg, containsString("\"foo\"")); + assertThat(msg, containsString("existing sub-variable")); + } + assertNull(thm.get("bar")); + } + + @Test + public void markupOutputParameter() throws Exception { + TemplateHTMLOutputModel html = HTMLOutputFormat.INSTANCE.fromMarkup("<p>a"); + + DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build(); + TemplateHashModel thm = (TemplateHashModel) ow.wrap(new TestBean()); + + { + TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m1"); + try { + m.exec(Collections.singletonList(html)); + fail(); + } catch (TemplateModelException e) { + assertThat(e.getMessage(), allOf( + containsString("String"), containsString("convert"), containsString("markup_output"), + containsString("Tip:"), containsString("?markup_string"))); + } + } + + { + TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m2"); + try { + m.exec(Collections.singletonList(html)); + fail(); + } catch (TemplateModelException e) { + assertThat(e.getMessage(), allOf( + containsString("Date"), containsString("convert"), containsString("markup_output"), + not(containsString("?markup_string")))); + } + } + + for (String methodName : new String[] { "mOverloaded", "mOverloaded3" }) { + TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get(methodName); + try { + m.exec(Collections.singletonList(html)); + fail(); + } catch (TemplateModelException e) { + assertThat(e.getMessage(), allOf( + containsString("No compatible overloaded"), + containsString("String"), containsString("markup_output"), + containsString("Tip:"), containsString("?markup_string"))); + } + } + + { + TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded2"); + try { + m.exec(Collections.singletonList(html)); + fail(); + } catch (TemplateModelException e) { + assertThat(e.getMessage(), allOf( + containsString("No compatible overloaded"), + containsString("Integer"), containsString("markup_output"), + not(containsString("?markup_string")))); + } + } + + { + TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded4"); + Object r = m.exec(Collections.singletonList(html)); + if (r instanceof TemplateScalarModel) { + r = ((TemplateScalarModel) r).getAsString(); + } + assertEquals("<p>a", r); + } + } + + public static class TestBean { + + public String getFoo() { + throw new RuntimeException("Dummy"); + } + + public void m1(String s) { + // nop + } + + public void m2(Date s) { + // nop + } + + public void mOverloaded(String s) { + // nop + } + + public void mOverloaded(Date d) { + // nop + } + + public void mOverloaded2(Integer n) { + // nop + } + + public void mOverloaded2(Date d) { + // nop + } + + public void mOverloaded3(String... s) { + // nop + } + + public void mOverloaded3(Date d) { + // nop + } + + public String mOverloaded4(String s) { + return s; + } + + public String mOverloaded4(TemplateHTMLOutputModel s) throws TemplateModelException { + return s.getOutputFormat().getMarkupString(s); + } + + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java new file mode 100644 index 0000000..92f59fb --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import static org.junit.Assert.*; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.model.TemplateHashModel; +import org.apache.freemarker.core.model.TemplateMethodModelEx; +import org.apache.freemarker.core.model.TemplateModel; +import org.apache.freemarker.core.model.TemplateModelException; +import org.apache.freemarker.core.model.TemplateScalarModel; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class FineTuneMethodAppearanceTest { + + @Test + public void newWayOfConfiguring() throws TemplateModelException { + DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0) + .methodAppearanceFineTuner(GetlessMethodsAsPropertyGettersRule.INSTANCE) + .exposeFields(true) + .build(); + checkIfProperlyWrapped(ow.wrap(new C())); + } + + private void checkIfProperlyWrapped(TemplateModel tm) throws TemplateModelException { + TemplateHashModel thm = (TemplateHashModel) tm; + assertEquals("v1", ((TemplateScalarModel) thm.get("v1")).getAsString()); + assertEquals("v2()", ((TemplateScalarModel) thm.get("v2")).getAsString()); + assertEquals("getV3()", ((TemplateScalarModel) thm.get("v3")).getAsString()); + assertTrue(thm.get("getV3") instanceof TemplateMethodModelEx); + } + + static public class C { + + public String v1 = "v1"; + + public String v2 = "v2"; + public String v2() { return "v2()"; } + + public String v3() { return "v3()"; } + public String getV3() { return "getV3()"; } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java new file mode 100644 index 0000000..716f863 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/GetlessMethodsAsPropertyGettersRule.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; + +class GetlessMethodsAsPropertyGettersRule implements MethodAppearanceFineTuner, SingletonCustomizer { + + static final GetlessMethodsAsPropertyGettersRule INSTANCE = new GetlessMethodsAsPropertyGettersRule(); + + // Can't be constructed from outside + private GetlessMethodsAsPropertyGettersRule() { } + + @Override + public void process( + DecisionInput in, Decision out) { + legacyProcess(in.getContainingClass(), in.getMethod(), out); + } + + /** This only exists as the tests need to call this through the deprecated method too. */ + public void legacyProcess( + Class clazz, Method m, Decision decision) { + if (m.getDeclaringClass() != Object.class + && m.getReturnType() != void.class + && m.getParameterTypes().length == 0) { + String mName = m.getName(); + if (!looksLikePropertyReadMethod(mName)) { + decision.setExposeMethodAs(null); + try { + decision.setExposeAsProperty(new PropertyDescriptor( + mName, clazz, mName, null)); + } catch (IntrospectionException e) { // Won't happen... + throw new RuntimeException(e); + } + } + } + } + + private static boolean looksLikePropertyReadMethod(String name) { + final int verbEnd; + if (name.startsWith("get")) verbEnd = 3; + else if (name.startsWith("is")) verbEnd = 2; + else return false; + + return name.length() == verbEnd || Character.isUpperCase(name.charAt(verbEnd)); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java new file mode 100644 index 0000000..599e6f2 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsApplicableTest.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +@SuppressWarnings("boxing") +public class IsApplicableTest extends TestCase { + + public IsApplicableTest(String name) { + super(name); + } + + public void testSingle() { + ArgumentTypes ats = new ArgumentTypes(new Object[] { new Object() }); + assertApplicable(ats, Object.class); + assertNotApplicable(ats, String.class); + assertNotApplicable(ats, CharSequence.class); + assertNotApplicable(ats, Integer.class); + assertNotApplicable(ats, Integer.TYPE); + + ats = new ArgumentTypes(new Object[] { "" }); + assertApplicable(ats, Object.class); + assertApplicable(ats, CharSequence.class); + assertApplicable(ats, String.class); + assertNotApplicable(ats, Integer.class); + assertNotApplicable(ats, Integer.TYPE); + + ats = new ArgumentTypes(new Object[] { 1 }); + assertApplicable(ats, Object.class); + assertNotApplicable(ats, CharSequence.class); + assertNotApplicable(ats, String.class); + assertNotApplicable(ats, Short.class); + assertNotApplicable(ats, Short.TYPE); + assertApplicable(ats, Integer.class); + assertApplicable(ats, Integer.TYPE); + assertApplicable(ats, Float.class); + assertApplicable(ats, Float.TYPE); + assertApplicable(ats, Double.class); + assertApplicable(ats, Double.TYPE); + assertApplicable(ats, BigDecimal.class); + assertApplicable(ats, BigInteger.class); + + ats = new ArgumentTypes(new Object[] { new OverloadedNumberUtil.IntegerOrByte(1, (byte) 1) }); + assertApplicable(ats, Object.class); + assertNotApplicable(ats, CharSequence.class); + assertNotApplicable(ats, String.class); + assertApplicable(ats, Short.class); + assertApplicable(ats, Short.TYPE); + assertApplicable(ats, Integer.class); + assertApplicable(ats, Integer.TYPE); + assertApplicable(ats, Float.class); + assertApplicable(ats, Float.TYPE); + assertApplicable(ats, Double.class); + assertApplicable(ats, Double.TYPE); + assertApplicable(ats, BigDecimal.class); + assertApplicable(ats, BigInteger.class); + + ats = new ArgumentTypes(new Object[] { 1.0f }); + assertApplicable(ats, Object.class); + assertNotApplicable(ats, CharSequence.class); + assertNotApplicable(ats, String.class); + assertNotApplicable(ats, Integer.class); + assertNotApplicable(ats, Integer.TYPE); + assertApplicable(ats, Float.class); + assertApplicable(ats, Float.TYPE); + assertApplicable(ats, Double.class); + assertApplicable(ats, Double.TYPE); + assertApplicable(ats, BigDecimal.class); + assertNotApplicable(ats, BigInteger.class); + + ats = new ArgumentTypes(new Object[] { null }); + assertApplicable(ats, Object.class); + assertApplicable(ats, String.class); + assertApplicable(ats, Integer.class); + assertNotApplicable(ats, Integer.TYPE); + assertNotApplicable(ats, Boolean.TYPE); + assertNotApplicable(ats, Object.class, Object.class); + assertNotApplicable(ats); + } + + public void testMulti() { + ArgumentTypes ats = new ArgumentTypes(new Object[] { new Object(), "", 1, true }); + assertApplicable(ats, Object.class, Object.class, Object.class, Object.class); + assertApplicable(ats, Object.class, String.class, Number.class, Boolean.class); + assertApplicable(ats, Object.class, CharSequence.class, Integer.class, Serializable.class); + assertApplicable(ats, Object.class, Comparable.class, Integer.TYPE, Serializable.class); + assertNotApplicable(ats, Object.class, String.class, Number.class, Number.class); + assertNotApplicable(ats, Object.class, StringBuilder.class, Number.class, Boolean.class); + assertNotApplicable(ats, int.class, Object.class, Object.class, Object.class); + assertNotApplicable(ats, Object.class, Object.class, Object.class); + assertNotApplicable(ats, Object.class, Object.class, Object.class, Object.class, Object.class); + } + + public void testNoParam() { + ArgumentTypes ats = new ArgumentTypes(new Object[] { }); + assertApplicable(ats); + assertNotApplicable(ats, Object.class); + } + + public void testVarags() { + Object[][] argLists = new Object[][] { + new Object[] { "", 1, 2, 3 }, + new Object[] { "", 1, (byte) 2, 3 }, + new Object[] { "", 1}, + new Object[] { "" }, + }; + for (Object[] args : argLists) { + ArgumentTypes ats = new ArgumentTypes(args); + assertApplicable(ats, true, String.class, int[].class); + assertApplicable(ats, true, String.class, Integer[].class); + assertApplicable(ats, true, Object.class, Comparable[].class); + assertApplicable(ats, true, Object.class, Object[].class); + assertNotApplicable(ats, true, StringBuilder.class, int[].class); + if (args.length > 1) { + assertNotApplicable(ats, true, String.class, String[].class); + } else { + assertApplicable(ats, true, String.class, String[].class); + } + } + } + + private void assertNotApplicable(ArgumentTypes ats, Class... paramTypes) { + assertNotApplicable(ats, false, paramTypes); + } + + private void assertNotApplicable(ArgumentTypes ats, boolean varargs, Class... paramTypes) { + List tested = new ArrayList(); + tested.add(new ReflectionCallableMemberDescriptor((Method) null, paramTypes)); + if (ats.getApplicables(tested, varargs).size() != 0) { + fail("Parameter types were applicable"); + } + } + + private void assertApplicable(ArgumentTypes ats, Class<?>... paramTypes) { + assertApplicable(ats, false, paramTypes); + } + + private void assertApplicable(ArgumentTypes ats, boolean varargs, Class<?>... paramTypes) { + List tested = new ArrayList(); + tested.add(new ReflectionCallableMemberDescriptor((Method) null, paramTypes)); + if (ats.getApplicables(tested, varargs).size() != 1) { + fail("Parameter types weren't applicable"); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java new file mode 100644 index 0000000..3de3f13 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/IsMoreSpecificParameterTypeTest.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +public class IsMoreSpecificParameterTypeTest extends TestCase { + + public IsMoreSpecificParameterTypeTest(String name) { + super(name); + } + + public void testFixed() { + assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, String.class, true, 0)); + assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, int.class, true, 0)); + + assertEquals(2, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Integer.class, true, 0)); + assertEquals(2, _MethodUtil.isMoreOrSameSpecificParameterType(boolean.class, Boolean.class, true, 0)); + + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, long.class, true, 0)); + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, double.class, true, 0)); + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Long.class, true, 0)); + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Double.class, true, 0)); + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Long.class, true, 0)); + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Double.class, true, 0)); + + assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(HashMap.class, Map.class, true, 0)); + assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, CharSequence.class, true, 0)); + assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Number.class, true, 0)); + assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Number.class, true, 0)); + + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Map.class, String.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, int.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Boolean.class, boolean.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, boolean.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Boolean.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, String.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, BigDecimal.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, Integer.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(long.class, Integer.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, int.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, BigDecimal.class, true, 0)); + } + + public void testBuggy() { + assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, String.class, false, 0)); + assertEquals(1, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, int.class, false, 0)); + + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Integer.class, false, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(boolean.class, Boolean.class, false, 0)); + + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, long.class, false, 0)); + assertEquals(3, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, double.class, false, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Long.class, false, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Double.class, false, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Long.class, false, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Double.class, false, 0)); + + assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(HashMap.class, Map.class, false, 0)); + assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(String.class, CharSequence.class, false, 0)); + assertEquals(4, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, Number.class, false, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Number.class, false, 0)); + + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Map.class, String.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, int.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Boolean.class, boolean.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, boolean.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, Boolean.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, String.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(int.class, BigDecimal.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, Integer.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(long.class, Integer.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Long.class, int.class, true, 0)); + assertEquals(0, _MethodUtil.isMoreOrSameSpecificParameterType(Integer.class, BigDecimal.class, true, 0)); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java new file mode 100644 index 0000000..96c1adf --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/Java7MembersOnlyDefaultObjectWrapper.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.Version; + +/** + * A hack to keep some unit tests producing exactly the same results on Java 8 as on Java 5-7, by hiding members + * added after Java 7. + */ +public class Java7MembersOnlyDefaultObjectWrapper extends DefaultObjectWrapper { + + private static final Set<String> POST_JAVA_7_MAP_METHODS = newHashSet( + "compute", "computeIfAbsent", "computeIfPresent", + "forEach", "getOrDefault", "merge", "putIfAbsent", "replace", "replaceAll"); + + private static final Set<String> POST_JAVA_7_ITERABLE_METHODS = newHashSet("forEach"); + private static final Set<String> POST_JAVA_7_COLLECTION_METHODS = newHashSet("parallelStream", "removeIf", "stream"); + private static final Set<String> POST_JAVA_7_LIST_METHODS = newHashSet("sort", "spliterator"); + + static final MethodAppearanceFineTuner POST_JAVA_7_FILTER = new MethodAppearanceFineTuner() { + + @Override + public void process(DecisionInput in, Decision out) { + Method m = in.getMethod(); + Class declCl = m.getDeclaringClass(); + if (Map.class.isAssignableFrom(declCl)) { + if (POST_JAVA_7_MAP_METHODS.contains(m.getName())) { + hideMember(out); + return; + } + } + if (Iterable.class.isAssignableFrom(declCl)) { + if (POST_JAVA_7_ITERABLE_METHODS.contains(m.getName())) { + hideMember(out); + return; + } + } + if (Collection.class.isAssignableFrom(declCl)) { + if (POST_JAVA_7_COLLECTION_METHODS.contains(m.getName())) { + hideMember(out); + return; + } + } + if (List.class.isAssignableFrom(declCl)) { + if (POST_JAVA_7_LIST_METHODS.contains(m.getName())) { + hideMember(out); + return; + } + } + } + + private void hideMember(Decision out) { + out.setExposeMethodAs(null); + out.setExposeAsProperty(null); + } + + }; + + public Java7MembersOnlyDefaultObjectWrapper(Version version) { + super(new DefaultObjectWrapper.Builder(version).methodAppearanceFineTuner(POST_JAVA_7_FILTER), true); + } + + private static <T> Set<T> newHashSet(T... items) { + HashSet<T> r = new HashSet<>(); + for (T item : items) { + r.add(item); + } + return r; + } + + public Java7MembersOnlyDefaultObjectWrapper() { + this(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java new file mode 100644 index 0000000..fa7ce29 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyObjectsOfDifferentClasses.java @@ -0,0 +1,249 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +// FMPP template source: +// ---- +// package org.apache.freemarker.core.model.impl; +// +// // FMPP template source: +// // ---- +// <#assign src><#include "ManyObjectsOfDifferentClasses.java.ftl" parse=false></#assign> +// ${src?trim?replace('(.*\r?\n)|.+', r'// $0', 'r')} +// // ---- +// +// <#assign MAX_CLA = 8 - 1> +// <#assign MAX_MET = 10 - 1> +// <#assign MAX_PRO = 10 - 1> +// +// public class ManyObjectsOfDifferentClasses { +// +// public static final Object[] OBJECTS = new Object[] { +// <#list 0..MAX_CLA as claI> +// new C${claI}(), +// </#list> +// }; +// +// <#list 0..MAX_CLA as claI> +// static public class C${claI} { +// <#list 0..MAX_PRO as proI> +// public int getP${proI}() { return ${claI} * 1000 + ${proI}; } +// </#list> +// <#list 0..MAX_MET as metI> +// public int m${metI}() { return ${claI} * 1000 + ${metI}; }; +// </#list> +// } +// </#list> +// +// } +// ---- + + +public class ManyObjectsOfDifferentClasses { + + public static final Object[] OBJECTS = new Object[] { + new C0(), + new C1(), + new C2(), + new C3(), + new C4(), + new C5(), + new C6(), + new C7(), + }; + + static public class C0 { + public int getP0() { return 0 * 1000 + 0; } + public int getP1() { return 0 * 1000 + 1; } + public int getP2() { return 0 * 1000 + 2; } + public int getP3() { return 0 * 1000 + 3; } + public int getP4() { return 0 * 1000 + 4; } + public int getP5() { return 0 * 1000 + 5; } + public int getP6() { return 0 * 1000 + 6; } + public int getP7() { return 0 * 1000 + 7; } + public int getP8() { return 0 * 1000 + 8; } + public int getP9() { return 0 * 1000 + 9; } + public int m0() { return 0 * 1000 + 0; }; + public int m1() { return 0 * 1000 + 1; }; + public int m2() { return 0 * 1000 + 2; }; + public int m3() { return 0 * 1000 + 3; }; + public int m4() { return 0 * 1000 + 4; }; + public int m5() { return 0 * 1000 + 5; }; + public int m6() { return 0 * 1000 + 6; }; + public int m7() { return 0 * 1000 + 7; }; + public int m8() { return 0 * 1000 + 8; }; + public int m9() { return 0 * 1000 + 9; }; + } + static public class C1 { + public int getP0() { return 1 * 1000 + 0; } + public int getP1() { return 1 * 1000 + 1; } + public int getP2() { return 1 * 1000 + 2; } + public int getP3() { return 1 * 1000 + 3; } + public int getP4() { return 1 * 1000 + 4; } + public int getP5() { return 1 * 1000 + 5; } + public int getP6() { return 1 * 1000 + 6; } + public int getP7() { return 1 * 1000 + 7; } + public int getP8() { return 1 * 1000 + 8; } + public int getP9() { return 1 * 1000 + 9; } + public int m0() { return 1 * 1000 + 0; }; + public int m1() { return 1 * 1000 + 1; }; + public int m2() { return 1 * 1000 + 2; }; + public int m3() { return 1 * 1000 + 3; }; + public int m4() { return 1 * 1000 + 4; }; + public int m5() { return 1 * 1000 + 5; }; + public int m6() { return 1 * 1000 + 6; }; + public int m7() { return 1 * 1000 + 7; }; + public int m8() { return 1 * 1000 + 8; }; + public int m9() { return 1 * 1000 + 9; }; + } + static public class C2 { + public int getP0() { return 2 * 1000 + 0; } + public int getP1() { return 2 * 1000 + 1; } + public int getP2() { return 2 * 1000 + 2; } + public int getP3() { return 2 * 1000 + 3; } + public int getP4() { return 2 * 1000 + 4; } + public int getP5() { return 2 * 1000 + 5; } + public int getP6() { return 2 * 1000 + 6; } + public int getP7() { return 2 * 1000 + 7; } + public int getP8() { return 2 * 1000 + 8; } + public int getP9() { return 2 * 1000 + 9; } + public int m0() { return 2 * 1000 + 0; }; + public int m1() { return 2 * 1000 + 1; }; + public int m2() { return 2 * 1000 + 2; }; + public int m3() { return 2 * 1000 + 3; }; + public int m4() { return 2 * 1000 + 4; }; + public int m5() { return 2 * 1000 + 5; }; + public int m6() { return 2 * 1000 + 6; }; + public int m7() { return 2 * 1000 + 7; }; + public int m8() { return 2 * 1000 + 8; }; + public int m9() { return 2 * 1000 + 9; }; + } + static public class C3 { + public int getP0() { return 3 * 1000 + 0; } + public int getP1() { return 3 * 1000 + 1; } + public int getP2() { return 3 * 1000 + 2; } + public int getP3() { return 3 * 1000 + 3; } + public int getP4() { return 3 * 1000 + 4; } + public int getP5() { return 3 * 1000 + 5; } + public int getP6() { return 3 * 1000 + 6; } + public int getP7() { return 3 * 1000 + 7; } + public int getP8() { return 3 * 1000 + 8; } + public int getP9() { return 3 * 1000 + 9; } + public int m0() { return 3 * 1000 + 0; }; + public int m1() { return 3 * 1000 + 1; }; + public int m2() { return 3 * 1000 + 2; }; + public int m3() { return 3 * 1000 + 3; }; + public int m4() { return 3 * 1000 + 4; }; + public int m5() { return 3 * 1000 + 5; }; + public int m6() { return 3 * 1000 + 6; }; + public int m7() { return 3 * 1000 + 7; }; + public int m8() { return 3 * 1000 + 8; }; + public int m9() { return 3 * 1000 + 9; }; + } + static public class C4 { + public int getP0() { return 4 * 1000 + 0; } + public int getP1() { return 4 * 1000 + 1; } + public int getP2() { return 4 * 1000 + 2; } + public int getP3() { return 4 * 1000 + 3; } + public int getP4() { return 4 * 1000 + 4; } + public int getP5() { return 4 * 1000 + 5; } + public int getP6() { return 4 * 1000 + 6; } + public int getP7() { return 4 * 1000 + 7; } + public int getP8() { return 4 * 1000 + 8; } + public int getP9() { return 4 * 1000 + 9; } + public int m0() { return 4 * 1000 + 0; }; + public int m1() { return 4 * 1000 + 1; }; + public int m2() { return 4 * 1000 + 2; }; + public int m3() { return 4 * 1000 + 3; }; + public int m4() { return 4 * 1000 + 4; }; + public int m5() { return 4 * 1000 + 5; }; + public int m6() { return 4 * 1000 + 6; }; + public int m7() { return 4 * 1000 + 7; }; + public int m8() { return 4 * 1000 + 8; }; + public int m9() { return 4 * 1000 + 9; }; + } + static public class C5 { + public int getP0() { return 5 * 1000 + 0; } + public int getP1() { return 5 * 1000 + 1; } + public int getP2() { return 5 * 1000 + 2; } + public int getP3() { return 5 * 1000 + 3; } + public int getP4() { return 5 * 1000 + 4; } + public int getP5() { return 5 * 1000 + 5; } + public int getP6() { return 5 * 1000 + 6; } + public int getP7() { return 5 * 1000 + 7; } + public int getP8() { return 5 * 1000 + 8; } + public int getP9() { return 5 * 1000 + 9; } + public int m0() { return 5 * 1000 + 0; }; + public int m1() { return 5 * 1000 + 1; }; + public int m2() { return 5 * 1000 + 2; }; + public int m3() { return 5 * 1000 + 3; }; + public int m4() { return 5 * 1000 + 4; }; + public int m5() { return 5 * 1000 + 5; }; + public int m6() { return 5 * 1000 + 6; }; + public int m7() { return 5 * 1000 + 7; }; + public int m8() { return 5 * 1000 + 8; }; + public int m9() { return 5 * 1000 + 9; }; + } + static public class C6 { + public int getP0() { return 6 * 1000 + 0; } + public int getP1() { return 6 * 1000 + 1; } + public int getP2() { return 6 * 1000 + 2; } + public int getP3() { return 6 * 1000 + 3; } + public int getP4() { return 6 * 1000 + 4; } + public int getP5() { return 6 * 1000 + 5; } + public int getP6() { return 6 * 1000 + 6; } + public int getP7() { return 6 * 1000 + 7; } + public int getP8() { return 6 * 1000 + 8; } + public int getP9() { return 6 * 1000 + 9; } + public int m0() { return 6 * 1000 + 0; }; + public int m1() { return 6 * 1000 + 1; }; + public int m2() { return 6 * 1000 + 2; }; + public int m3() { return 6 * 1000 + 3; }; + public int m4() { return 6 * 1000 + 4; }; + public int m5() { return 6 * 1000 + 5; }; + public int m6() { return 6 * 1000 + 6; }; + public int m7() { return 6 * 1000 + 7; }; + public int m8() { return 6 * 1000 + 8; }; + public int m9() { return 6 * 1000 + 9; }; + } + static public class C7 { + public int getP0() { return 7 * 1000 + 0; } + public int getP1() { return 7 * 1000 + 1; } + public int getP2() { return 7 * 1000 + 2; } + public int getP3() { return 7 * 1000 + 3; } + public int getP4() { return 7 * 1000 + 4; } + public int getP5() { return 7 * 1000 + 5; } + public int getP6() { return 7 * 1000 + 6; } + public int getP7() { return 7 * 1000 + 7; } + public int getP8() { return 7 * 1000 + 8; } + public int getP9() { return 7 * 1000 + 9; } + public int m0() { return 7 * 1000 + 0; }; + public int m1() { return 7 * 1000 + 1; }; + public int m2() { return 7 * 1000 + 2; }; + public int m3() { return 7 * 1000 + 3; }; + public int m4() { return 7 * 1000 + 4; }; + public int m5() { return 7 * 1000 + 5; }; + public int m6() { return 7 * 1000 + 6; }; + public int m7() { return 7 * 1000 + 7; }; + public int m8() { return 7 * 1000 + 8; }; + public int m9() { return 7 * 1000 + 9; }; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java new file mode 100644 index 0000000..dd73bee --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ManyStaticsOfDifferentClasses.java @@ -0,0 +1,236 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +// FMPP template source: +// ---- +// package org.apache.freemarker.core.model.impl; +// +// // FMPP template source: +// // ---- +// <#assign src><#include "ManyStaticsOfDifferentClasses.java.ftl" parse=false></#assign> +// ${src?trim?replace('(.*\r?\n)|.+', r'// $0', 'r')} +// // ---- +// +// <#assign MAX_CLA = 8 - 1> +// <#assign MAX_MET = 10 - 1> +// <#assign MAX_PRO = 10 - 1> +// +// public class ManyStaticsOfDifferentClasses { +// +// private ManyStaticsOfDifferentClasses() { } +// +// <#list 0..MAX_CLA as claI> +// static public class C${claI} { +// <#list 0..MAX_PRO as proI> +// public static int p${proI} = ${claI} * 1000 + ${proI}; +// </#list> +// <#list 0..MAX_MET as metI> +// public static int m${metI}() { return ${claI} * 1000 + ${metI}; }; +// </#list> +// } +// </#list> +// +// } +// ---- + + +public class ManyStaticsOfDifferentClasses { + + private ManyStaticsOfDifferentClasses() { } + + static public class C0 { + public static int p0 = 0 * 1000 + 0; + public static int p1 = 0 * 1000 + 1; + public static int p2 = 0 * 1000 + 2; + public static int p3 = 0 * 1000 + 3; + public static int p4 = 0 * 1000 + 4; + public static int p5 = 0 * 1000 + 5; + public static int p6 = 0 * 1000 + 6; + public static int p7 = 0 * 1000 + 7; + public static int p8 = 0 * 1000 + 8; + public static int p9 = 0 * 1000 + 9; + public static int m0() { return 0 * 1000 + 0; }; + public static int m1() { return 0 * 1000 + 1; }; + public static int m2() { return 0 * 1000 + 2; }; + public static int m3() { return 0 * 1000 + 3; }; + public static int m4() { return 0 * 1000 + 4; }; + public static int m5() { return 0 * 1000 + 5; }; + public static int m6() { return 0 * 1000 + 6; }; + public static int m7() { return 0 * 1000 + 7; }; + public static int m8() { return 0 * 1000 + 8; }; + public static int m9() { return 0 * 1000 + 9; }; + } + static public class C1 { + public static int p0 = 1 * 1000 + 0; + public static int p1 = 1 * 1000 + 1; + public static int p2 = 1 * 1000 + 2; + public static int p3 = 1 * 1000 + 3; + public static int p4 = 1 * 1000 + 4; + public static int p5 = 1 * 1000 + 5; + public static int p6 = 1 * 1000 + 6; + public static int p7 = 1 * 1000 + 7; + public static int p8 = 1 * 1000 + 8; + public static int p9 = 1 * 1000 + 9; + public static int m0() { return 1 * 1000 + 0; }; + public static int m1() { return 1 * 1000 + 1; }; + public static int m2() { return 1 * 1000 + 2; }; + public static int m3() { return 1 * 1000 + 3; }; + public static int m4() { return 1 * 1000 + 4; }; + public static int m5() { return 1 * 1000 + 5; }; + public static int m6() { return 1 * 1000 + 6; }; + public static int m7() { return 1 * 1000 + 7; }; + public static int m8() { return 1 * 1000 + 8; }; + public static int m9() { return 1 * 1000 + 9; }; + } + static public class C2 { + public static int p0 = 2 * 1000 + 0; + public static int p1 = 2 * 1000 + 1; + public static int p2 = 2 * 1000 + 2; + public static int p3 = 2 * 1000 + 3; + public static int p4 = 2 * 1000 + 4; + public static int p5 = 2 * 1000 + 5; + public static int p6 = 2 * 1000 + 6; + public static int p7 = 2 * 1000 + 7; + public static int p8 = 2 * 1000 + 8; + public static int p9 = 2 * 1000 + 9; + public static int m0() { return 2 * 1000 + 0; }; + public static int m1() { return 2 * 1000 + 1; }; + public static int m2() { return 2 * 1000 + 2; }; + public static int m3() { return 2 * 1000 + 3; }; + public static int m4() { return 2 * 1000 + 4; }; + public static int m5() { return 2 * 1000 + 5; }; + public static int m6() { return 2 * 1000 + 6; }; + public static int m7() { return 2 * 1000 + 7; }; + public static int m8() { return 2 * 1000 + 8; }; + public static int m9() { return 2 * 1000 + 9; }; + } + static public class C3 { + public static int p0 = 3 * 1000 + 0; + public static int p1 = 3 * 1000 + 1; + public static int p2 = 3 * 1000 + 2; + public static int p3 = 3 * 1000 + 3; + public static int p4 = 3 * 1000 + 4; + public static int p5 = 3 * 1000 + 5; + public static int p6 = 3 * 1000 + 6; + public static int p7 = 3 * 1000 + 7; + public static int p8 = 3 * 1000 + 8; + public static int p9 = 3 * 1000 + 9; + public static int m0() { return 3 * 1000 + 0; }; + public static int m1() { return 3 * 1000 + 1; }; + public static int m2() { return 3 * 1000 + 2; }; + public static int m3() { return 3 * 1000 + 3; }; + public static int m4() { return 3 * 1000 + 4; }; + public static int m5() { return 3 * 1000 + 5; }; + public static int m6() { return 3 * 1000 + 6; }; + public static int m7() { return 3 * 1000 + 7; }; + public static int m8() { return 3 * 1000 + 8; }; + public static int m9() { return 3 * 1000 + 9; }; + } + static public class C4 { + public static int p0 = 4 * 1000 + 0; + public static int p1 = 4 * 1000 + 1; + public static int p2 = 4 * 1000 + 2; + public static int p3 = 4 * 1000 + 3; + public static int p4 = 4 * 1000 + 4; + public static int p5 = 4 * 1000 + 5; + public static int p6 = 4 * 1000 + 6; + public static int p7 = 4 * 1000 + 7; + public static int p8 = 4 * 1000 + 8; + public static int p9 = 4 * 1000 + 9; + public static int m0() { return 4 * 1000 + 0; }; + public static int m1() { return 4 * 1000 + 1; }; + public static int m2() { return 4 * 1000 + 2; }; + public static int m3() { return 4 * 1000 + 3; }; + public static int m4() { return 4 * 1000 + 4; }; + public static int m5() { return 4 * 1000 + 5; }; + public static int m6() { return 4 * 1000 + 6; }; + public static int m7() { return 4 * 1000 + 7; }; + public static int m8() { return 4 * 1000 + 8; }; + public static int m9() { return 4 * 1000 + 9; }; + } + static public class C5 { + public static int p0 = 5 * 1000 + 0; + public static int p1 = 5 * 1000 + 1; + public static int p2 = 5 * 1000 + 2; + public static int p3 = 5 * 1000 + 3; + public static int p4 = 5 * 1000 + 4; + public static int p5 = 5 * 1000 + 5; + public static int p6 = 5 * 1000 + 6; + public static int p7 = 5 * 1000 + 7; + public static int p8 = 5 * 1000 + 8; + public static int p9 = 5 * 1000 + 9; + public static int m0() { return 5 * 1000 + 0; }; + public static int m1() { return 5 * 1000 + 1; }; + public static int m2() { return 5 * 1000 + 2; }; + public static int m3() { return 5 * 1000 + 3; }; + public static int m4() { return 5 * 1000 + 4; }; + public static int m5() { return 5 * 1000 + 5; }; + public static int m6() { return 5 * 1000 + 6; }; + public static int m7() { return 5 * 1000 + 7; }; + public static int m8() { return 5 * 1000 + 8; }; + public static int m9() { return 5 * 1000 + 9; }; + } + static public class C6 { + public static int p0 = 6 * 1000 + 0; + public static int p1 = 6 * 1000 + 1; + public static int p2 = 6 * 1000 + 2; + public static int p3 = 6 * 1000 + 3; + public static int p4 = 6 * 1000 + 4; + public static int p5 = 6 * 1000 + 5; + public static int p6 = 6 * 1000 + 6; + public static int p7 = 6 * 1000 + 7; + public static int p8 = 6 * 1000 + 8; + public static int p9 = 6 * 1000 + 9; + public static int m0() { return 6 * 1000 + 0; }; + public static int m1() { return 6 * 1000 + 1; }; + public static int m2() { return 6 * 1000 + 2; }; + public static int m3() { return 6 * 1000 + 3; }; + public static int m4() { return 6 * 1000 + 4; }; + public static int m5() { return 6 * 1000 + 5; }; + public static int m6() { return 6 * 1000 + 6; }; + public static int m7() { return 6 * 1000 + 7; }; + public static int m8() { return 6 * 1000 + 8; }; + public static int m9() { return 6 * 1000 + 9; }; + } + static public class C7 { + public static int p0 = 7 * 1000 + 0; + public static int p1 = 7 * 1000 + 1; + public static int p2 = 7 * 1000 + 2; + public static int p3 = 7 * 1000 + 3; + public static int p4 = 7 * 1000 + 4; + public static int p5 = 7 * 1000 + 5; + public static int p6 = 7 * 1000 + 6; + public static int p7 = 7 * 1000 + 7; + public static int p8 = 7 * 1000 + 8; + public static int p9 = 7 * 1000 + 9; + public static int m0() { return 7 * 1000 + 0; }; + public static int m1() { return 7 * 1000 + 1; }; + public static int m2() { return 7 * 1000 + 2; }; + public static int m3() { return 7 * 1000 + 3; }; + public static int m4() { return 7 * 1000 + 4; }; + public static int m5() { return 7 * 1000 + 5; }; + public static int m6() { return 7 * 1000 + 6; }; + public static int m7() { return 7 * 1000 + 7; }; + public static int m8() { return 7 * 1000 + 8; }; + public static int m9() { return 7 * 1000 + 9; }; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java new file mode 100644 index 0000000..9e175e5 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MiscNumericalOperationsTest.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.junit.Assert; + +import junit.framework.TestCase; + +public class MiscNumericalOperationsTest extends TestCase { + + public MiscNumericalOperationsTest(String name) { + super(name); + } + + public void testForceUnwrappedNumberToType() { + // Usual type to to all other types: + Double n = Double.valueOf(123.75); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Short.class), Short.valueOf(n.shortValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Short.TYPE), Short.valueOf(n.shortValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Byte.class), Byte.valueOf(n.byteValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Byte.TYPE), Byte.valueOf(n.byteValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Integer.class), Integer.valueOf(n.intValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Integer.TYPE), Integer.valueOf(n.intValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Long.class), Long.valueOf(n.longValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Long.TYPE), Long.valueOf(n.longValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Float.class), Float.valueOf(n.floatValue())); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Float.TYPE), Float.valueOf(n.floatValue())); + assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Double.class) == n); + assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Double.TYPE) == n); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, BigInteger.class), new BigInteger("123")); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(n, BigDecimal.class), new BigDecimal("123.75")); + + // Cases of conversion to BigDecimal: + BigDecimal bd = new BigDecimal("123"); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(new BigInteger("123"), BigDecimal.class), bd); + assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(bd, BigDecimal.class) == bd); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Long.valueOf(123), BigDecimal.class), bd); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Double.valueOf(123), BigDecimal.class), bd); + + // Cases of conversion to BigInteger: + BigInteger bi = new BigInteger("123"); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(new BigDecimal("123.6"), BigInteger.class), bi); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType( + new OverloadedNumberUtil.IntegerBigDecimal(new BigDecimal("123")), BigInteger.class), bi); + assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(bi, BigInteger.class) == bi); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Long.valueOf(123), BigInteger.class), bi); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(Double.valueOf(123.6), BigInteger.class), bi); + + assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(n, Number.class) == n); + assertNull(DefaultObjectWrapper.forceUnwrappedNumberToType(n, RationalNumber.class)); + RationalNumber r = new RationalNumber(1, 2); + assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(r, RationalNumber.class) == r); + assertTrue(DefaultObjectWrapper.forceUnwrappedNumberToType(r, Number.class) == r); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, Double.class), Double.valueOf(0.5)); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, BigDecimal.class), new BigDecimal("0.5")); + assertEquals(DefaultObjectWrapper.forceUnwrappedNumberToType(r, BigInteger.class), BigInteger.ZERO); + } + + @SuppressWarnings("boxing") + public void testForceNumberArgumentsToParameterTypes() { + OverloadedMethodsSubset oms = new OverloadedFixArgsMethods(); + Class[] paramTypes = new Class[] { Short.TYPE, Short.class, Double.TYPE, BigDecimal.class, BigInteger.class }; + Object[] args; + + args = newArgs(); + oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }); + Assert.assertArrayEquals( + args, + new Object[] { (short) 123, (short) 123, 123.75, new BigDecimal("123.75"), BigInteger.valueOf(123) }); + + args = newArgs(); + oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0, 0, 0, 0, 0 }); + Assert.assertArrayEquals(args, newArgs()); + + args = newArgs(); + oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 8, 8, 8, 8, 8 }); + Assert.assertArrayEquals(args, newArgs()); + + args = newArgs(); + oms.forceNumberArgumentsToParameterTypes(args, paramTypes, new int[] { 0xFFFF, 0, 0xFFFF, 0, 0xFFFF }); + Assert.assertArrayEquals( + args, + new Object[] { (short) 123, 123.75, 123.75, 123.75, BigInteger.valueOf(123) }); + } + + @SuppressWarnings("boxing") + private Object[] newArgs() { + return new Object[] { 123.75, 123.75, 123.75, 123.75, 123.75 }; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java new file mode 100644 index 0000000..0b0a614 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelAPINewInstanceTest.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.test.TestUtil; + +import junit.framework.TestCase; + +public class ModelAPINewInstanceTest extends TestCase { + + private DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build(); + + public ModelAPINewInstanceTest(String name) { + super(name); + } + + @SuppressWarnings("boxing") + public void test() throws Exception { + testClassConstructors(""); + testClassConstructors("int... [1]", 1); + testClassConstructors("int 1, int 2", 1, 2); + testClassConstructors("int... [1, 2, 3]", 1, 2, 3); + testClassConstructors("int... [1, 2, 3]", 1, (byte) 2, (short) 3); + try { + testClassConstructors("int... [1, 2, 3]", 1, 2, (long) 3); + fail(); + } catch (NoSuchMethodException e) { + // Expected + } + + testClassConstructors("int 1, int 2", (byte) 1, (short) 2); + testClassConstructors("double 1.0, double 2.0", (long) 1, (short) 2); + testClassConstructors("double 1.0, double 2.0", 1, 2f); + testClassConstructors("Integer null, Integer null", null, null); + testClassConstructors("Integer null, Integer 1", null, 1); + testClassConstructors("int 1, String s", 1, "s"); + testClassConstructors("int 1, String null", 1, null); + testClassConstructors("Object null, Object s", null, "s"); + testClassConstructors("Object 1.0, Object s", 1f, "s"); + + testClassConstructors("Object s, int... [1, 2]", "s", 1, 2); + testClassConstructors("Object s, int... []", "s"); + + testClassConstructors2("int 1, int 2", (byte) 1, (short) 2); + try { + testClassConstructors2("int 1, int 2", 1, 2L); + fail(); + } catch (NoSuchMethodException e) { + // Expected + } + try { + testClassConstructors2("", "", ""); + fail(); + } catch (NoSuchMethodException e) { + // Expected + } + try { + testClassConstructors2("int 1", 1); + fail(); + } catch (NoSuchMethodException e) { + // Expected + } + try { + testClassConstructors2(""); + fail(); + } catch (NoSuchMethodException e) { + // Expected + } + } + + private void testClassConstructors(String expected, Object... args) throws Exception { + testCall(expected, Constructors.class, args); + } + + private void testClassConstructors2(String expected, Object... args) throws Exception { + testCall(expected, Constructors2.class, args); + } + + private void testCall(String expected, Class cl, Object... args) throws Exception { + Object obj = _ModelAPI.newInstance(cl, args, ow); + assertEquals(expected, obj.toString()); + } + + public static class Constructors { + private final String s; + + public Constructors() { s = ""; } + + public Constructors(int x, int y) { s = "int " + x + ", int " + y; } + public Constructors(int x, String y) { s = "int " + x + ", String " + y; } + public Constructors(int x, long y) { s = "int " + x + ", long " + y; } + public Constructors(double x, double y) { s = "double " + x + ", double " + y; } + public Constructors(Integer x, Integer y) { s = "Integer " + x + ", Integer " + y; } + public Constructors(Object x, Object y) { s = "Object " + x + ", Object " + y; } + + public Constructors(int... xs) { s = "int... " + TestUtil.arrayToString(xs); } + public Constructors(Object x, int... ys) { s = "Object " + x + ", int... " + TestUtil.arrayToString(ys); } + + @Override + public String toString() { + return s; + } + } + + public static class Constructors2 { + private final String s; + + public Constructors2(int x, int y) { s = "int " + x + ", int " + y; } + + @Override + public String toString() { + return s; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/28a276c8/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java new file mode 100644 index 0000000..2498859 --- /dev/null +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ModelCacheTest.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.freemarker.core.model.impl; + +import static org.junit.Assert.*; + +import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.model.TemplateModel; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ModelCacheTest { + + @Test + public void modelCacheOff() throws Exception { + DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build(); + assertFalse(ow.getUseModelCache()); // default is off + + String s = "foo"; + assertNotSame(ow.wrap(s), ow.wrap(s)); + + C c = new C(); + assertNotSame(ow.wrap(c), ow.wrap(c)); + } + + @Test + @Ignore // ModelCache is current removed in FM3 + public void modelCacheOn() throws Exception { + DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0) + .useModelCache(true).build(); + assertTrue(ow.getUseModelCache()); + + TestBean obj = new TestBean(); + assertSame(ow.wrap(obj), ow.wrap(obj)); + + C c = new C(); + TemplateModel wrappedC = ow.wrap(c); + assertSame(wrappedC, ow.wrap(c)); + + ow.clearClassIntrospecitonCache(); + assertNotSame(wrappedC, ow.wrap(c)); + assertSame(ow.wrap(c), ow.wrap(c)); + } + + static public class C { } + + public static class TestBean { + // + } + +}
