/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.wicket;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.mock.MockApplication;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Response;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.cycle.RequestCycleContext;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Tests component events
*
* @author igor
*/
public class ComponentEventsTest
{
private WicketTester tester;
private TestPage page;
private TestContainer c1;
private TestContainer c12;
private TestContainer c13;
private TestContainer c134;
private TestComponent c135;
private TestComponent c6;
private TestApplication application;
private TestSession session;
private TestRequestCycle cycle;
private Testable[] all;
private Object stop;
/** */
@Before
public void setup()
{
tester = new WicketTester(new TestApplication());
application = (TestApplication)tester.getApplication();
session = (TestSession)tester.getSession();
cycle = (TestRequestCycle)tester.getRequestCycle();
page = new TestPage();
c1 = new TestContainer("c1");
c12 = new TestContainer("c12");
c13 = new TestContainer("c13");
c134 = new TestContainer("c134");
c135 = new TestComponent("c135");
c6 = new TestComponent("c6");
page.add(c1);
c1.add(c12);
c1.add(c13);
c13.add(c134);
c13.add(c135);
page.add(c6);
all = new Testable[] { page, c1, c12, c13, c134, c135, c6, application, session, cycle };
stop = null;
}
/** */
@After
public void destroy()
{
tester.destroy();
}
/** */
@Test
public void testBreadth_Application()
{
page.send(tester.getApplication(), Broadcast.BREADTH, new Payload());
assertPath(application, session, cycle, page, c1, c12, c13, c134, c135, c6);
}
/** */
@Test
public void testBreadth_Session()
{
page.send(tester.getSession(), Broadcast.BREADTH, new Payload());
assertPath(session, cycle, page, c1, c12, c13, c134, c135, c6);
}
/** */
@Test
public void testBreadth_Cycle()
{
page.send(tester.getRequestCycle(), Broadcast.BREADTH, new Payload());
assertPath(cycle, page, c1, c12, c13, c134, c135, c6);
}
/** */
@Test
public void testBreadth_Page()
{
page.send(page, Broadcast.BREADTH, new Payload());
assertPath(page, c1, c12, c13, c134, c135, c6);
}
/** */
@Test
public void testBreadth_Container()
{
page.send(c13, Broadcast.BREADTH, new Payload());
assertPath(c13, c134, c135);
}
/** */
@Test
public void testBreadth_Component()
{
page.send(c6, Broadcast.BREADTH, new Payload());
assertPath(c6);
}
/** */
@Test
public void testBreadth_Application_Stop()
{
stop = application;
page.send(application, Broadcast.BREADTH, new Payload());
assertPath(application);
}
/** */
@Test
public void testBreadth_Session_Stop()
{
stop = session;
page.send(application, Broadcast.BREADTH, new Payload());
assertPath(application, session);
}
/** */
@Test
public void testBreadth_Cycle_Stop()
{
stop = cycle;
page.send(application, Broadcast.BREADTH, new Payload());
assertPath(application, session, cycle);
}
/** */
@Test
public void testBreadth_Page_Stop()
{
stop = page;
page.send(application, Broadcast.BREADTH, new Payload());
assertPath(application, session, cycle, page);
}
/** */
@Test
public void testBreadth_Component_Stop()
{
stop = c13;
page.send(application, Broadcast.BREADTH, new Payload());
assertPath(application, session, cycle, page, c1, c12, c13);
}
/** */
@Test
public void testDepth_Application()
{
page.send(application, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1, c6, page, cycle, session, application);
}
/** */
@Test
public void testDepth_Session()
{
page.send(session, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1, c6, page, cycle, session);
}
/** */
@Test
public void testDepth_Cycle()
{
page.send(cycle, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1, c6, page, cycle);
}
/** */
@Test
public void testDepth_Page()
{
page.send(page, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1, c6, page);
}
/** */
@Test
public void testDepth_Container()
{
page.send(c1, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1);
}
/** */
@Test
public void testDepth_Component()
{
page.send(c6, Broadcast.DEPTH, new Payload());
assertPath(c6);
}
/** */
@Test
public void testDepth_Session_Stop()
{
stop = session;
page.send(application, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1, c6, page, cycle, session);
}
/** */
@Test
public void testDepth_Cycle_Stop()
{
stop = cycle;
page.send(application, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1, c6, page, cycle);
}
/** */
@Test
public void testDepth_Page_Stop()
{
stop = page;
page.send(application, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1, c6, page);
}
/** */
@Test
public void testDepth_Component_Stop()
{
stop = c1;
page.send(application, Broadcast.DEPTH, new Payload());
assertPath(c12, c134, c135, c13, c1);
}
/**
*
*/
@Test
public void testBubble_Component()
{
c6.send(c135, Broadcast.BUBBLE, new Payload());
assertPath(c135, c13, c1, page, cycle, session, application);
}
/** */
@Test
public void testBubble_Page()
{
c6.send(page, Broadcast.BUBBLE, new Payload());
assertPath(page, cycle, session, application);
}
/** */
@Test
public void testBubble_Cycle()
{
c6.send(cycle, Broadcast.BUBBLE, new Payload());
assertPath(cycle, session, application);
}
/** */
@Test
public void testBubble_Session()
{
c6.send(session, Broadcast.BUBBLE, new Payload());
assertPath(session, application);
}
/** */
@Test
public void testBubble_Application()
{
c6.send(application, Broadcast.BUBBLE, new Payload());
assertPath(application);
}
/** */
@Test
public void testBubble_Component_Stop()
{
stop = c1;
c6.send(c135, Broadcast.BUBBLE, new Payload());
assertPath(c135, c13, c1);
}
/** */
@Test
public void testBubble_Component_Page()
{
stop = page;
c6.send(c135, Broadcast.BUBBLE, new Payload());
assertPath(c135, c13, c1, page);
}
/** */
@Test
public void testBubble_Cycle_Stop()
{
stop = cycle;
c6.send(c135, Broadcast.BUBBLE, new Payload());
assertPath(c135, c13, c1, page, cycle);
}
/** */
@Test
public void testBubble_Session_Stop()
{
stop = session;
c6.send(c135, Broadcast.BUBBLE, new Payload());
assertPath(c135, c13, c1, page, cycle, session);
}
@Test
public void testBehaviorBreadth()
{
TestComponent c = new TestComponent("c");
TestBehavior b1 = new TestBehavior();
TestBehavior b2 = new TestBehavior();
c.add(b1, b2);
c.send(c, Broadcast.BREADTH, new Payload());
assertEquals(0, c.sequence);
assertEquals(1, b1.sequence);
assertEquals(2, b2.sequence);
assertEquals(-1, application.sequence);
assertEquals(-1, session.sequence);
assertEquals(-1, cycle.sequence);
assertEquals(-1, page.sequence);
}
@Test
public void testBehaviorExact()
{
TestComponent c = new TestComponent("c");
TestBehavior b1 = new TestBehavior();
TestBehavior b2 = new TestBehavior();
c.add(b1, b2);
c.send(c, Broadcast.EXACT, new Payload());
assertEquals(0, c.sequence);
assertEquals(1, b1.sequence);
assertEquals(2, b2.sequence);
assertEquals(-1, application.sequence);
assertEquals(-1, session.sequence);
assertEquals(-1, cycle.sequence);
assertEquals(-1, page.sequence);
}
@Test
public void testPageExact()
{
TestComponent c = new TestComponent("c");
TestBehavior b1 = new TestBehavior();
c.add(b1);
page.add(c);
TestBehavior b2 = new TestBehavior();
page.add(b2);
c.send(page, Broadcast.EXACT, new Payload());
assertEquals(-1, c.sequence);
assertEquals(-1, b1.sequence);
assertEquals(1, b2.sequence);
assertEquals(-1, application.sequence);
assertEquals(-1, session.sequence);
assertEquals(-1, cycle.sequence);
assertEquals(0, page.sequence);
}
@Test
public void testApplicationExact()
{
TestComponent c = new TestComponent("c");
TestBehavior b1 = new TestBehavior();
TestBehavior b2 = new TestBehavior();
c.add(b1, b2);
c.send(c.getApplication(), Broadcast.EXACT, new Payload());
assertEquals(-1, c.sequence);
assertEquals(-1, b1.sequence);
assertEquals(-1, b2.sequence);
assertEquals(0, application.sequence);
assertEquals(-1, session.sequence);
assertEquals(-1, cycle.sequence);
assertEquals(-1, page.sequence);
}
@Test
public void testSessionExact()
{
TestComponent c = new TestComponent("c");
TestBehavior b1 = new TestBehavior();
TestBehavior b2 = new TestBehavior();
c.add(b1, b2);
c.send(c.getSession(), Broadcast.EXACT, new Payload());
assertEquals(-1, c.sequence);
assertEquals(-1, b1.sequence);
assertEquals(-1, b2.sequence);
assertEquals(-1, application.sequence);
assertEquals(0, session.sequence);
assertEquals(-1, cycle.sequence);
assertEquals(-1, page.sequence);
}
@Test
public void testRequestCycleExact()
{
TestComponent c = new TestComponent("c");
TestBehavior b1 = new TestBehavior();
TestBehavior b2 = new TestBehavior();
c.add(b1, b2);
c.send(c.getRequestCycle(), Broadcast.EXACT, new Payload());
assertEquals(-1, c.sequence);
assertEquals(-1, b1.sequence);
assertEquals(-1, b2.sequence);
assertEquals(-1, application.sequence);
assertEquals(-1, session.sequence);
assertEquals(0, cycle.sequence);
assertEquals(-1, page.sequence);
}
@Test
public void testBehavior_stop()
{
TestComponent c = new TestComponent("c");
TestBehavior b1 = new TestBehavior()
{
@Override
public void onEvent(Component component, IEvent<?> event)
{
super.onEvent(component, event);
event.stop();
}
};
TestBehavior b2 = new TestBehavior();
c.add(b1, b2);
c.send(c, Broadcast.BREADTH, new Payload());
assertEquals(0, c.sequence);
assertEquals(1, b1.sequence);
assertEquals(-1, b2.sequence);
}
private void assertPath(Testable... testables)
{
List<Testable> remaining = new ArrayList<Testable>(Arrays.asList(all));
for (int i = 0; i < testables.length; i++)
{
Assert.assertEquals("checking path element " + i, i, testables[i].getSequence());
remaining.remove(testables[i]);
}
for (Testable testable : remaining)
{
String name = testable.getClass().getSimpleName();
if (testable instanceof Component && !(testable instanceof Page))
{
name += "#" + ((Component)testable).getId();
}
Assert.assertEquals(name + " should not have been visited, but was.", -1,
testable.getSequence());
}
}
private static interface Testable
{
int getSequence();
}
private class TestApplication extends MockApplication implements Testable
{
int sequence = -1;
@Override
public void onEvent(IEvent<?> event)
{
super.onEvent(event);
Payload payload = (Payload)event.getPayload();
sequence = payload.next();
if (stop == this)
{
event.stop();
}
}
@Override
public Session newSession(Request request, Response response)
{
return new TestSession(request);
}
@Override
protected void init()
{
super.init();
setRequestCycleProvider(TestRequestCycle::new);
}
@Override
public int getSequence()
{
return sequence;
}
}
private class TestSession extends WebSession implements Testable
{
private static final long serialVersionUID = 1L;
int sequence = -1;
public TestSession(Request request)
{
super(request);
}
@Override
public int getSequence()
{
return sequence;
}
@Override
public void onEvent(IEvent<?> event)
{
super.onEvent(event);
Payload payload = (Payload)event.getPayload();
sequence = payload.next();
if (stop == this)
{
event.stop();
}
}
}
private class TestRequestCycle extends RequestCycle implements Testable
{
int sequence = -1;
public TestRequestCycle(RequestCycleContext context)
{
super(context);
}
@Override
public int getSequence()
{
return sequence;
}
@Override
public void onEvent(IEvent<?> event)
{
super.onEvent(event);
Payload payload = (Payload)event.getPayload();
sequence = payload.next();
if (stop == this)
{
event.stop();
}
}
}
private class TestPage extends WebPage implements Testable
{
private static final long serialVersionUID = 1L;
int sequence = -1;
public TestPage()
{
}
@Override
public int getSequence()
{
return sequence;
}
@Override
public void onEvent(IEvent<?> event)
{
super.onEvent(event);
Payload payload = (Payload)event.getPayload();
sequence = payload.next();
// System.out.println(getId());
if (stop == this)
{
event.stop();
}
}
}
private class TestContainer extends WebMarkupContainer implements Testable
{
private static final long serialVersionUID = 1L;
int sequence = -1;
public TestContainer(String id)
{
super(id);
}
@Override
public void onEvent(IEvent<?> event)
{
super.onEvent(event);
Payload payload = (Payload)event.getPayload();
sequence = payload.next();
// System.out.println(getId());
if (stop == this)
{
event.stop();
}
}
@Override
public int getSequence()
{
return sequence;
}
}
private class TestComponent extends WebComponent implements Testable
{
private static final long serialVersionUID = 1L;
int sequence = -1;
public TestComponent(String id)
{
super(id);
}
@Override
public void onEvent(IEvent<?> event)
{
super.onEvent(event);
Payload payload = (Payload)event.getPayload();
sequence = payload.next();
// System.out.println(getId());
if (stop == this)
{
event.stop();
}
}
@Override
public int getSequence()
{
return sequence;
}
}
private class TestBehavior extends Behavior implements Testable
{
private static final long serialVersionUID = 1L;
int sequence = -1;
Component component;
@Override
public void onEvent(Component component, IEvent<?> event)
{
super.onEvent(component, event);
Payload payload = (Payload)event.getPayload();
sequence = payload.next();
this.component = component;
// System.out.println(getId());
if (stop == this)
{
event.stop();
}
}
@Override
public int getSequence()
{
return sequence;
}
}
private static class Payload
{
private int counter;
public int next()
{
return counter++;
}
}
}