<?xml version="1.0"?>
<!--
  Copyright 2002,2004 The Apache Software Foundation.
  
  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.
-->

<test:suite 
    xmlns:j="jelly:core"
    xmlns:b="jelly:beanshell" 
    xmlns:test="jelly:junit">

<test:case name="testPropertyWithDot">

    <j:set var="foo.bar" value="hello"/>
    
    <b:script>
        System.out.println( "foo.bar: " + context.getVariable("foo.bar") );

        if (context.getVariable("foo.bar") == null) {
            throw new Exception("Failed: no foo.bar defined: " + foo_bar);
        }
        context.setVariable("foo.bar", "worked");
  </b:script>

    <test:assertEquals expected="worked" actual="${foo.bar}"/>
        
</test:case>

<test:case name="testDotConversion">

    <j:set var="foo.bar" value="hello"/>
    
    <b:script>
        System.out.println( "foo.bar: " + foo_bar );

        if (foo_bar == null) {
             throw new Exception("Failed: no foo.bar defined: " + foo_bar);
        }
        context.setVariable("foo.bar", "worked");
  </b:script>

    <test:assertEquals expected="worked" actual="${foo.bar}"/>
        
</test:case>

</test:suite>
