/*
 $Id$

 Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.

 Redistribution and use of this software and associated documentation
 ("Software"), with or without modification, are permitted provided
 that the following conditions are met:

 1. Redistributions of source code must retain copyright
    statements and notices.  Redistributions must also contain a
    copy of this document.

 2. Redistributions in binary form must reproduce the
    above copyright notice, this list of conditions and the
    following disclaimer in the documentation and/or other
    materials provided with the distribution.

 3. The name "groovy" must not be used to endorse or promote
    products derived from this Software without prior written
    permission of The Codehaus.  For written permission,
    please contact info@codehaus.org.

 4. Products derived from this Software may not be called "groovy"
    nor may "groovy" appear in their names without prior written
    permission of The Codehaus. "groovy" is a registered
    trademark of The Codehaus.

 5. Due credit should be given to The Codehaus -
    http://groovy.codehaus.org/

 THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
 ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 OF THE POSSIBILITY OF SUCH DAMAGE.

 */

package org.codehaus.groovy.runtime;

import groovy.lang.GString;
import groovy.util.GroovyTestCase;

/**
 * Tests method invocation
 * 
 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
 * @version $Revision$
 */
public class InvokeConstructorTest extends GroovyTestCase {

    protected Invoker invoker = new Invoker();

    public void testInvokeConstructorNoParams() throws Throwable {
        assertConstructor(new DummyBean(), new Object[0]);
    }

    public void testInvokeConstructorOneParam() throws Throwable {
        assertConstructor(new DummyBean("Bob"), "Bob");
    }

    public void testInvokeConstructorOneParamWhichIsNull() throws Throwable {
        assertConstructor(new DummyBean("Bob", new Integer(1707)), new Object[] { "Bob", new Integer(1707)});
    }

    public void testConstructorWithGStringCoercion() throws Throwable {
        GString gstring = new GString(new Object[] { new Integer(123)}) {
            public String[] getStrings() {
                return new String[] { "" };
            }
        };

        Object expected = new Long(gstring.toString());

        assertConstructor(expected, new Object[] { gstring });
    }

    protected void assertConstructor(Object expected, Object arguments) throws Throwable {
        Object value = invoke(expected.getClass().getName(), arguments);

        assertEquals("Invoking overloaded method for arguments: " + InvokerHelper.toString(arguments), expected, value);
    }

    protected Object invoke(String type, Object args) throws Throwable {
        try {
            return invoker.invokeConstructor(type, args);
        }
        catch (InvokerInvocationException e) {
            throw e.getCause();
        }
    }
}
