Package org.apache.tapestry.form

Source Code of org.apache.tapestry.form.TestFormSupport

// Copyright 2005 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.tapestry.form;

import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.hivemind.test.HiveMindTestCase;
import org.apache.tapestry.FormSupport;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRender;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.NestedMarkupWriter;
import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.StaleLinkException;
import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.valid.IValidationDelegate;
import org.easymock.MockControl;

/**
* Tests for {@link org.apache.tapestry.form.FormSupportImpl}.
*
* @author Howard M. Lewis Ship
* @since 4.0
*/
public class TestFormSupport extends HiveMindTestCase
{

    private IRender newComponentRenderBody(final FormSupport fs, final IFormComponent component,
            final IMarkupWriter nested)
    {
        return newComponentsRenderBody(fs, new IFormComponent[]
        { component }, nested);
    }

    private IRender newComponentsRenderBody(final FormSupport fs, final IFormComponent[] component,
            final IMarkupWriter nested)
    {
        return new IRender()
        {
            public void render(IMarkupWriter writer, IRequestCycle cycle)
            {
                assertEquals("Writer argument must be nested instance.", nested, writer);

                for (int i = 0; i < component.length; i++)
                    fs.getElementId(component[i]);
            }
        };
    }

    private IFormComponent newFormComponent(String id, String name)
    {
        MockControl componentc = newControl(IFormComponent.class);
        final IFormComponent component = (IFormComponent) componentc.getMock();

        component.getId();
        componentc.setReturnValue(id);

        component.setName(name);

        return component;
    }

    private IFormComponent newFormComponent(String id, String extendedId, Location location)
    {
        MockControl componentc = newControl(IFormComponent.class);
        final IFormComponent component = (IFormComponent) componentc.getMock();

        component.getId();
        componentc.setReturnValue(id);

        component.getExtendedId();
        componentc.setReturnValue(extendedId);

        component.getLocation();
        componentc.setReturnValue(location);

        return component;
    }

    private IValidationDelegate newDelegate()
    {
        return (IValidationDelegate) newMock(IValidationDelegate.class);
    }

    private IMarkupWriter newWriter()
    {
        return (IMarkupWriter) newMock(IMarkupWriter.class);
    }

    private NestedMarkupWriter newNestedWriter()
    {
        return (NestedMarkupWriter) newMock(NestedMarkupWriter.class);
    }

    public void testComplexRender()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        final IFormComponent barney1 = newFormComponent("barney", "barney");
        final IFormComponent wilma = newFormComponent("wilma", "wilma");
        final IFormComponent barney2 = newFormComponent("barney", "barney$0");

        IRender body = newComponentsRenderBody(fs, new IFormComponent[]
        { barney1, wilma, barney2 }, nested);

        form.setBody(body);

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "barney,wilma,barney$0");
        trainHidden(writer, "service", "fred");

        nested.close();

        writer.end();

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testComplexRewind()
    {
        IMarkupWriter writer = newWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        IValidationDelegate delegate = newDelegate();

        MockForm form = new MockForm(delegate);

        cycle.isRewound(form);
        cyclec.setReturnValue(true);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        delegate.clear();

        trainCycleForRewind(cyclec, cycle, "barney,wilma,barney$0", null);

        final IFormComponent barney1 = newFormComponent("barney", "barney");
        final IFormComponent wilma = newFormComponent("wilma", "wilma");
        final IFormComponent barney2 = newFormComponent("barney", "barney$0");

        IRender body = newComponentsRenderBody(fs, new IFormComponent[]
        { barney1, wilma, barney2 }, writer);

        form.setBody(body);

        replayControls();

        fs.rewind();

        verifyControls();
    }

    public void testComplexSubmitEventHandler()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        form.setBody(new IRender()
        {
            public void render(IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.addEventHandler(FormEventType.SUBMIT, "mySubmit1");
                fs.addEventHandler(FormEventType.SUBMIT, "mySubmit2");
                fs.addEventHandler(FormEventType.SUBMIT, "mySubmit3");
            }
        });

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "");
        trainHidden(writer, "service", "fred");

        nested.close();

        writer.end();

        trainForPageSupport(
                cyclec,
                cycle,
                "document.myform.onsubmit = function ()\n{\n  return mySubmit1() &&\n    mySubmit2() &&\n    mySubmit3();\n}\n");

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testEncodingType()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        form.setBody(new IRender()
        {
            public void render(IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.setEncodingType("foo/bar");
            }
        });

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");
        writer.attribute("name", "myform");
        writer.attribute("enctype", "foo/bar");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "");
        trainHidden(writer, "service", "fred");

        nested.close();

        writer.end();

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testHiddenValues()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        form.setBody(new IRender()
        {
            public void render(IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.addHiddenValue("hidden1", "value1");
                fs.addHiddenValue("hidden2", "id2", "value2");
            }
        });

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "");
        trainHidden(writer, "service", "fred");
        trainHidden(writer, "hidden1", "value1");
        trainHidden(writer, "hidden2", "id2", "value2");

        nested.close();

        writer.end();

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testInvalidEncodingType()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        form.setBody(new IRender()
        {
            public void render(IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.setEncodingType("foo/bar");
                fs.setEncodingType("zip/zap");
            }
        });

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        replayControls();

        try
        {
            fs.render("post", render, link);
            unreachable();
        }
        catch (ApplicationRuntimeException ex)
        {
            assertEquals(
                    "Components within form SomePage/myform have requested conflicting encoding types 'foo/bar' and 'zip/zap'.",
                    ex.getMessage());
            assertSame(form, ex.getComponent());
        }

        verifyControls();
    }

    public void testRenderExtraReservedIds()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        final IFormComponent component = newFormComponent("action", "action$0");

        IRender body = newComponentRenderBody(fs, component, nested);

        form.setBody(body);

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "action" });

        link.getParameterValues("action");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "action$0");
        trainHidden(writer, "action", "fred");
        trainHidden(writer, "reservedids", "action");

        nested.close();

        writer.end();

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testResetEventHandler()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        form.setBody(new IRender()
        {
            public void render(IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.addEventHandler(FormEventType.RESET, "myReset1");
                fs.addEventHandler(FormEventType.RESET, "myReset2");
            }
        });

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "");
        trainHidden(writer, "service", "fred");

        nested.close();

        writer.end();

        trainForPageSupport(
                cyclec,
                cycle,
                "document.myform.onreset = function ()\n{\n  myReset1();\n  myReset2();\n}\n");

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testRewindExtraReservedIds()
    {
        IMarkupWriter writer = newWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
        IValidationDelegate delegate = newDelegate();

        MockForm form = new MockForm(delegate);

        cycle.isRewound(form);
        cyclec.setReturnValue(true);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        delegate.clear();

        trainCycleForRewind(cyclec, cycle, "action$0", "action");

        final IFormComponent component = newFormComponent("action", "action$0");

        IRender body = newComponentRenderBody(fs, component, writer);

        form.setBody(body);

        replayControls();

        fs.rewind();

        verifyControls();
    }

    public void testRewindMismatch()
    {

        IMarkupWriter writer = newWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        IValidationDelegate delegate = newDelegate();

        MockForm form = new MockForm(delegate);

        cycle.isRewound(form);
        cyclec.setReturnValue(true);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        Location l = newLocation();

        delegate.clear();

        // So, the scenario here is that component "pebbles" was inside
        // some kind of conditional that evaluated to true during the render,
        // but is now false on the rewind.

        trainCycleForRewind(cyclec, cycle, "barney,wilma,pebbles,barney$0", null);

        final IFormComponent barney1 = newFormComponent("barney", "barney");
        final IFormComponent wilma = newFormComponent("wilma", "wilma");
        final IFormComponent barney2 = newFormComponent("barney", "SomePage/barney", l);

        IRender body = newComponentsRenderBody(fs, new IFormComponent[]
        { barney1, wilma, barney2 }, writer);

        form.setBody(body);

        replayControls();

        try
        {
            fs.rewind();
            unreachable();
        }
        catch (StaleLinkException ex)
        {
            assertEquals(
                    "Rewind of form SomePage/myform expected allocated id #3 to be 'pebbles', but was 'barney$0' (requested by component SomePage/barney).",
                    ex.getMessage());
            assertSame(barney2, ex.getComponent());
            assertSame(l, ex.getLocation());
        }

        verifyControls();
    }

    public void testRewindTooLong()
    {
        IMarkupWriter writer = newWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        IValidationDelegate delegate = newDelegate();

        MockForm form = new MockForm(delegate);

        cycle.isRewound(form);
        cyclec.setReturnValue(true);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        Location l = newLocation();

        delegate.clear();

        // So, the scenario here is that component "barney" was inside
        // some kind of loop that executed once on the render, but twice
        // on the rewind (i.e., an additional object was added in between).

        trainCycleForRewind(cyclec, cycle, "barney,wilma", null);

        final IFormComponent barney1 = newFormComponent("barney", "barney");
        final IFormComponent wilma = newFormComponent("wilma", "wilma");
        final IFormComponent barney2 = newFormComponent("barney", "SomePage/barney", l);

        IRender body = newComponentsRenderBody(fs, new IFormComponent[]
        { barney1, wilma, barney2 }, writer);

        form.setBody(body);

        replayControls();

        try
        {
            fs.rewind();
            unreachable();
        }
        catch (StaleLinkException ex)
        {
            assertEquals(
                    "Rewind of form SomePage/myform expected only 2 form elements, but an additional id was requested by component SomePage/barney.",
                    ex.getMessage());
            assertSame(barney2, ex.getComponent());
            assertSame(l, ex.getLocation());
        }

        verifyControls();
    }

    public void testRewindTooShort()
    {
        Location l = newLocation();
        IMarkupWriter writer = newWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        IValidationDelegate delegate = newDelegate();

        MockForm form = new MockForm(delegate, l);

        cycle.isRewound(form);
        cyclec.setReturnValue(true);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        delegate.clear();

        // So, the scenario here is that component "barney" was inside
        // some kind of loop that executed twice on the render, but only once
        // on the rewind (i.e., the object was deleted in between).

        trainCycleForRewind(cyclec, cycle, "barney,wilma,barney$0", null);

        final IFormComponent barney1 = newFormComponent("barney", "barney");
        final IFormComponent wilma = newFormComponent("wilma", "wilma");

        IRender body = newComponentsRenderBody(fs, new IFormComponent[]
        { barney1, wilma }, writer);

        form.setBody(body);

        replayControls();

        try
        {
            fs.rewind();
            unreachable();
        }
        catch (StaleLinkException ex)
        {
            assertEquals(
                    "Rewind of form SomePage/myform expected 1 more form elements, starting with id 'barney$0'.",
                    ex.getMessage());
            assertSame(form, ex.getComponent());
            assertSame(l, ex.getLocation());
        }

        verifyControls();
    }

    public void testSimpleRender()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        final IFormComponent component = newFormComponent("barney", "barney");

        IRender body = newComponentRenderBody(fs, component, nested);

        form.setBody(body);

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "barney");
        trainHidden(writer, "service", "fred");

        nested.close();

        writer.end();

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testSimpleRenderWithDeferredRunnable()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        IRender body = new IRender()
        {

            public void render(final IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.addDeferredRunnable(new Runnable()
                {

                    public void run()
                    {
                        writer.print("DEFERRED");
                    }

                });
            }

        };

        form.setBody(body);

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "");
        trainHidden(writer, "service", "fred");

        // EasyMock can't fully verify that this gets called at the right moment, nor can we truly
        // prove (well, except by looking at the code), that the deferred runnables execute at the
        // right time.

        nested.print("DEFERRED");

        nested.close();

        writer.end();

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    public void testSimpleRewind()
    {
        IMarkupWriter writer = newWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        IValidationDelegate delegate = newDelegate();

        MockForm form = new MockForm(delegate);

        cycle.isRewound(form);
        cyclec.setReturnValue(true);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        delegate.clear();

        trainCycleForRewind(cyclec, cycle, "barney", null);

        final IFormComponent component = newFormComponent("barney", "barney");

        IRender body = newComponentRenderBody(fs, component, writer);

        form.setBody(body);

        replayControls();

        fs.rewind();

        verifyControls();
    }

    public void testSimpleRewindWithDeferredRunnable()
    {
        IMarkupWriter writer = newWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        IValidationDelegate delegate = newDelegate();

        MockForm form = new MockForm(delegate);

        cycle.isRewound(form);
        cyclec.setReturnValue(true);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        delegate.clear();
       
        trainCycleForRewind(cyclec, cycle, "", null);

        writer.print("DEFERRED");

        replayControls();

        IRender body = new IRender()
        {

            public void render(final IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.addDeferredRunnable(new Runnable()
                {
                    public void run()
                    {
                        writer.print("DEFERRED");
                    }

                });
            }

        };

        form.setBody(body);

        fs.rewind();

        verifyControls();
    }

    public void testSimpleSubmitEventHandler()
    {
        MockControl writerc = newControl(IMarkupWriter.class);
        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();

        NestedMarkupWriter nested = newNestedWriter();

        MockControl cyclec = newControl(IRequestCycle.class);
        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();

        MockForm form = new MockForm();

        cycle.isRewound(form);
        cyclec.setReturnValue(false);

        replayControls();

        final FormSupport fs = new FormSupportImpl(writer, cycle, form);

        verifyControls();

        form.setBody(new IRender()
        {
            public void render(IMarkupWriter writer, IRequestCycle cycle)
            {
                fs.addEventHandler(FormEventType.SUBMIT, "mySubmit");
            }
        });

        MockControl linkc = newControl(ILink.class);
        ILink link = (ILink) linkc.getMock();

        IRender render = (IRender) newMock(IRender.class);

        link.getParameterNames();
        linkc.setReturnValue(new String[]
        { "service" });

        link.getParameterValues("service");
        linkc.setReturnValue(new String[]
        { "fred" });

        writer.getNestedWriter();
        writerc.setReturnValue(nested);

        link.getURL(null, false);
        linkc.setReturnValue("/app");

        writer.begin("form");
        writer.attribute("method", "post");
        writer.attribute("action", "/app");

        writer.attribute("name", "myform");

        render.render(writer, cycle);

        writer.println();

        trainHidden(writer, "formids", "");
        trainHidden(writer, "service", "fred");

        nested.close();

        writer.end();

        trainForPageSupport(cyclec, cycle, "document.myform.onsubmit = mySubmit;\n");

        replayControls();

        fs.render("post", render, link);

        verifyControls();
    }

    private void trainCycleForRewind(MockControl cyclec, IRequestCycle cycle, String allocatedIds,
            String reservedIds)
    {
        cycle.getParameter(FormSupportImpl.FORM_IDS);
        cyclec.setReturnValue(allocatedIds);

        cycle.getParameter(FormSupportImpl.RESERVED_FORM_IDS);
        cyclec.setReturnValue(reservedIds);
    }

    private void trainForPageSupport(MockControl cyclec, IRequestCycle cycle, String initialization)
    {
        PageRenderSupport prs = (PageRenderSupport) newMock(PageRenderSupport.class);

        prs.addInitializationScript(initialization);

        cycle.getAttribute(TapestryUtils.PAGE_RENDER_SUPPORT_ATTRIBUTE);
        cyclec.setReturnValue(prs);
    }

    private void trainHidden(IMarkupWriter writer, String name, String value)
    {
        writer.beginEmpty("input");
        writer.attribute("type", "hidden");
        writer.attribute("name", name);
        writer.attribute("value", value);
        writer.println();
    }

    private void trainHidden(IMarkupWriter writer, String name, String id, String value)
    {
        writer.beginEmpty("input");
        writer.attribute("type", "hidden");
        writer.attribute("name", name);
        writer.attribute("id", id);
        writer.attribute("value", value);
        writer.println();
    }
}
TOP

Related Classes of org.apache.tapestry.form.TestFormSupport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.