[ 
https://issues.apache.org/jira/browse/VELOCITY-986?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Patrick Barry updated VELOCITY-986:
-----------------------------------
    Description: 
We recently tried to upgrade to 2.4 and 2.4.1 and both had this issue, so we 
had to rollback. We have a template looking like this:
[https://my.example.com?size=$|https://my.example.com/?size=$]

{input.size}

 
In our VelocityContext, we have have an InnerContext values that should be used.
IE

{"size"= "1089", "name"="tyler", "age"="28"}

 
In versions 2.3 and below, this would evaluate to 
[https://my.example.com?size=1089|https://my.example.com/?size=1089]
With newest versions, it gives us the number of items in our map. So
[https://my.example.com?size=3|https://my.example.com/?size=1089]
 
Here is a unit test of our usage.  It uses 2 Velocity Contexts
 
{code}
import org.apache.commons.collections4.map.CaseInsensitiveMap;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.junit.Test;

import java.io.StringWriter;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class VelocityRegressionTest {

    @Test
    public void testVelocityTemplate() {
        VelocityEngine velocityEngine = new VelocityEngine();
        velocityEngine.init();
        CaseInsensitiveMap<String, Object> innerMap = new 
CaseInsensitiveMap<>();
        //Size is both an operation on "Map", as well a key within it
        innerMap.put("size", "1098");
        innerMap.put("name", "Tyler");
        innerMap.put("try", "1");

        CaseInsensitiveMap<String, Object> outerMap = new 
CaseInsensitiveMap<>();
        outerMap.put("input", innerMap);
        
        VelocityContext context = new VelocityContext(outerMap);
        StringWriter sw = new StringWriter();

        //This works correctly
        String template = "https://my.example.com?size=${input.name}";;
        Velocity.evaluate(context, sw, "", template);
        assertEquals("https://my.example.com?size=Tyler";, sw.toString());

        sw = new StringWriter();
        // This notation works, however it is not the one we used. Just 
including it here to show that one notation still works as expected.
        template = "https://my.example.com?size=${input[\"size\"]}";;
        Velocity.evaluate(context, sw, "", template);
        assertEquals("https://my.example.com?size=1098";, sw.toString());

        //THIS DEMONSTRATES THE BREAKING CHANGE
        sw = new StringWriter();
        // In versions 2.4+, size evaluates to the size function of maps, not 
the field inside the map with the same name. This is what broke.
        // Seems like order of operations is flipped
        template = "https://my.example.com?size=${input.size}";;
        Velocity.evaluate(context, sw, "", template);
        assertEquals("https://my.example.com?size=1098";, sw.toString());
    }
}{code}

  was:
We recently tried to upgrade to 2.4 and 2.4.1 and both had this issue, so we 
had to rollback. We have a template looking like this:
[https://my.example.com?size=$|https://my.example.com/?size=$]

{input.size}

 
In our VelocityContext, we have have an InnerContext values that should be used.
IE

{"size"= "1089", "name"="tyler", "age"="28"}

 
In versions 2.3 and below, this would evaluate to 
[https://my.example.com?size=1089|https://my.example.com/?size=1089]
With newest versions, it gives us the number of items in our map. So
[https://my.example.com?size=3|https://my.example.com/?size=1089]
 
Here is a unit test of our usage.  It uses 2 Velocity Contexts
 
{code:keyword}
import org.apache.commons.collections4.map.CaseInsensitiveMap;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.junit.Test;

import java.io.StringWriter;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class VelocityRegressionTest {

    @Test
    public void testVelocityTemplate() {
        VelocityEngine velocityEngine = new VelocityEngine();
        velocityEngine.init();
        CaseInsensitiveMap<String, Object> innerMap = new 
CaseInsensitiveMap<>();
        //Size is both an operation on "Map", as well a key within it
        innerMap.put("size", "1098");
        innerMap.put("name", "Tyler");
        innerMap.put("try", "1");

        CaseInsensitiveMap<String, Object> outerMap = new 
CaseInsensitiveMap<>();
        outerMap.put("input", innerMap);
        
        VelocityContext context = new VelocityContext(outerMap);
        StringWriter sw = new StringWriter();

        //This works correctly
        String template = "https://my.example.com?size=${input.name}";;
        Velocity.evaluate(context, sw, "", template);
        assertEquals("https://my.example.com?size=Tyler";, sw.toString());

        sw = new StringWriter();
        // This notation works, however it is not the one we used. Just 
including it here to show that one notation still works as expected.
        template = "https://my.example.com?size=${input[\"size\"]}";;
        Velocity.evaluate(context, sw, "", template);
        assertEquals("https://my.example.com?size=1098";, sw.toString());

        //THIS DEMONSTRATES THE BREAKING CHANGE
        sw = new StringWriter();
        // In versions 2.4+, size evaluates to the size function of maps, not 
the field inside the map with the same name. This is what broke.
        // Seems like order of operations is flipped
        template = "https://my.example.com?size=${input.size}";;
        Velocity.evaluate(context, sw, "", template);
        assertEquals("https://my.example.com?size=1098";, sw.toString());
    }
}{code}


> Breaking change- Map size method is called, instead of provided size property
> -----------------------------------------------------------------------------
>
>                 Key: VELOCITY-986
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-986
>             Project: Velocity
>          Issue Type: Bug
>          Components: Engine
>    Affects Versions: 2.4, 2.4.1
>            Reporter: Patrick Barry
>            Priority: Major
>
> We recently tried to upgrade to 2.4 and 2.4.1 and both had this issue, so we 
> had to rollback. We have a template looking like this:
> [https://my.example.com?size=$|https://my.example.com/?size=$]
> {input.size}
>  
> In our VelocityContext, we have have an InnerContext values that should be 
> used.
> IE
> {"size"= "1089", "name"="tyler", "age"="28"}
>  
> In versions 2.3 and below, this would evaluate to 
> [https://my.example.com?size=1089|https://my.example.com/?size=1089]
> With newest versions, it gives us the number of items in our map. So
> [https://my.example.com?size=3|https://my.example.com/?size=1089]
>  
> Here is a unit test of our usage.  It uses 2 Velocity Contexts
>  
> {code}
> import org.apache.commons.collections4.map.CaseInsensitiveMap;
> import org.apache.velocity.VelocityContext;
> import org.apache.velocity.app.Velocity;
> import org.apache.velocity.app.VelocityEngine;
> import org.junit.Test;
> import java.io.StringWriter;
> import static org.junit.jupiter.api.Assertions.assertEquals;
> public class VelocityRegressionTest {
>     @Test
>     public void testVelocityTemplate() {
>         VelocityEngine velocityEngine = new VelocityEngine();
>         velocityEngine.init();
>         CaseInsensitiveMap<String, Object> innerMap = new 
> CaseInsensitiveMap<>();
>         //Size is both an operation on "Map", as well a key within it
>         innerMap.put("size", "1098");
>         innerMap.put("name", "Tyler");
>         innerMap.put("try", "1");
>         CaseInsensitiveMap<String, Object> outerMap = new 
> CaseInsensitiveMap<>();
>         outerMap.put("input", innerMap);
>         
>         VelocityContext context = new VelocityContext(outerMap);
>         StringWriter sw = new StringWriter();
>         //This works correctly
>         String template = "https://my.example.com?size=${input.name}";;
>         Velocity.evaluate(context, sw, "", template);
>         assertEquals("https://my.example.com?size=Tyler";, sw.toString());
>         sw = new StringWriter();
>         // This notation works, however it is not the one we used. Just 
> including it here to show that one notation still works as expected.
>         template = "https://my.example.com?size=${input[\"size\"]}";;
>         Velocity.evaluate(context, sw, "", template);
>         assertEquals("https://my.example.com?size=1098";, sw.toString());
>         //THIS DEMONSTRATES THE BREAKING CHANGE
>         sw = new StringWriter();
>         // In versions 2.4+, size evaluates to the size function of maps, not 
> the field inside the map with the same name. This is what broke.
>         // Seems like order of operations is flipped
>         template = "https://my.example.com?size=${input.size}";;
>         Velocity.evaluate(context, sw, "", template);
>         assertEquals("https://my.example.com?size=1098";, sw.toString());
>     }
> }{code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@velocity.apache.org
For additional commands, e-mail: dev-h...@velocity.apache.org

Reply via email to