/*
 * Copyright 2006 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.
 */

package org.apache.geronimo.gshell.command;

import junit.framework.TestCase;

import java.util.HashMap;
import java.util.Map;

/**
 * Unit tests for the {@link VariablesMap} class.
 *
 * @version $Id$
 */
public class VariablesMapTest
    extends TestCase
{
    public void testConstructorArgsNull() throws Exception {
        try {
            new VariablesMap((Map<String,Object>)null);
            fail("Accepted a null value");
        }
        catch (IllegalArgumentException expected) {
            // ignore
        }

        try {
            new VariablesMap((Variables)null);
            fail("Accepted a null value");
        }
        catch (IllegalArgumentException expected) {
            // ignore
        }

        try {
            new VariablesMap(new HashMap<String,Object>(), null);
            fail("Accepted a null value");
        }
        catch (IllegalArgumentException expected) {
            // ignore
        }

        // Happy day
        new VariablesMap(new HashMap<String,Object>(), new VariablesMap());
    }

    /*
    public void testSetNameIsNull() throws Exception {
        try {
            new VariablesMap().set(null, null);
            fail("Accepted a null value");
        }
        catch (IllegalArgumentException expected) {
            // ignore
        }
    }
    */

    public void testSet() throws Exception {
        VariablesMap vars = new VariablesMap();
        String name = "a";
        Object value = new Object();

        assertFalse(vars.contains(name));
        vars.set(name, value);
        assertTrue(vars.contains(name));

        Object obj = vars.get(name);
        assertEquals(value, obj);

        String str = vars.names().next();
        assertEquals(name, str);
    }

    public void testSetAsImmutable() throws Exception {
        VariablesMap vars = new VariablesMap();
        String name = "a";
        Object value = new Object();

        assertTrue(vars.isMutable(name));
        vars.set(name, value, false);
        assertFalse(vars.isMutable(name));

        try {
            vars.set(name, value);
            fail("Set an immutable variable");
        }
        catch (Variables.ImmutableVariableException expected) {
            // ignore
        }
    }

    public void testSetAsImmutableInParent() throws Exception {
        Variables parent = new VariablesMap();
        VariablesMap vars = new VariablesMap(parent);
        String name = "a";
        Object value = new Object();

        parent.set(name, value, false);
        assertFalse(parent.isMutable(name));
        assertFalse(vars.isMutable(name));

        try {
            vars.set(name, value);
            fail("Set an immutable variable");
        }
        catch (Variables.ImmutableVariableException expected) {
            // ignore
        }
    }

    public void testGet() throws Exception {
        VariablesMap vars = new VariablesMap();
        String name = "a";
        Object value = new Object();

        Object obj1 = vars.get(name);
        assertNull(obj1);

        vars.set(name, value);
        Object obj2 = vars.get(name);
        assertSame(value, obj2);
    }

    public void testGetUsingDefault() throws Exception {
        VariablesMap vars = new VariablesMap();
        String name = "a";
        Object value = new Object();

        Object obj1 = vars.get(name);
        assertNull(obj1);

        Object obj2 = vars.get(name, value);
        assertSame(value, obj2);
    }

    public void testGetCloaked() throws Exception {
        Variables parent = new VariablesMap();
        VariablesMap vars = new VariablesMap(parent);
        String name = "a";
        Object value = new Object();

        parent.set(name, value);
        Object obj1 = vars.get(name);
        assertEquals(value, obj1);

        Object value2 = new Object();
        vars.set(name, value2);

        Object obj2 = vars.get(name);
        assertSame(value2, obj2);
        assertNotSame(value, obj2);
    }

    public void testUnsetAsImmutable() throws Exception {
        VariablesMap vars = new VariablesMap();
        String name = "a";
        Object value = new Object();

        assertTrue(vars.isMutable(name));
        vars.set(name, value, false);
        assertFalse(vars.isMutable(name));

        try {
            vars.unset(name);
            fail("Unset an immutable variable");
        }
        catch (Variables.ImmutableVariableException expected) {
            // ignore
        }
    }

    public void testUnsetAsImmutableInParent() throws Exception {
        Variables parent = new VariablesMap();
        VariablesMap vars = new VariablesMap(parent);
        String name = "a";
        Object value = new Object();

        parent.set(name, value, false);
        assertFalse(parent.isMutable(name));
        assertFalse(vars.isMutable(name));

        try {
            vars.unset(name);
            fail("Unset an immutable variable");
        }
        catch (Variables.ImmutableVariableException expected) {
            // ignore
        }
    }

    public void testCloaking() throws Exception {
        Variables parent = new VariablesMap();
        VariablesMap vars = new VariablesMap(parent);
        String name = "a";
        Object value = new Object();

        parent.set(name, value);
        assertFalse(parent.isCloaked(name));
        assertFalse(vars.isCloaked(name));

        vars.set(name, new Object());
        assertTrue(vars.isCloaked(name));
    }

    public void testParent() throws Exception {
        Variables parent = new VariablesMap();
        assertNull(parent.parent());

        VariablesMap vars = new VariablesMap(parent);
        assertNotNull(vars.parent());

        assertEquals(parent, vars.parent());
    }
}

@@ -734,16 +734,43 @@
 til.Map;
+%0Aimport java.util.Iterator;
 %0A%0A/**%0A *
@@ -6388,11 +6388,573 @@
 );%0A    %7D
+%0A%0A    public void testNames() throws Exception %7B%0A        VariablesMap vars = new VariablesMap();%0A        Iterator%3CString%3E iter = vars.names();%0A        assertNotNull(iter);%0A        assertFalse(iter.hasNext());%0A    %7D%0A%0A    public void testNamesImmutable() throws Exception %7B%0A        VariablesMap vars = new VariablesMap();%0A        vars.set(%22a%22, %22b%22);%0A%0A        Iterator%3CString%3E iter = vars.names();%0A        iter.next();%0A%0A        try %7B%0A            iter.remove();%0A        %7D%0A        catch (UnsupportedOperationException expected) %7B%0A            // ignore%0A        %7D%0A    %7D
 %0A%7D%0A

Improve tests