/* * 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.devutils.stateless; import org.apache.wicket.Component; import org.apache.wicket.MarkupContainer; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.util.tester.DummyHomePage; import org.apache.wicket.util.tester.WicketTester; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * @author Marat Radchenko */ public class StatelessCheckerTest extends Assert { @StatelessComponent public static class StatelessPage extends DummyHomePage { private static final long serialVersionUID = 1L; } @StatelessComponent private static class StatelessLabel extends Label { private static final long serialVersionUID = 1L; public StatelessLabel(final String id) { super(id); } } @StatelessComponent private static class StatefulMarkupContainer extends MarkupContainer { private static final long serialVersionUID = 1L; public StatefulMarkupContainer(String id) { super(id); } @Override public boolean getStatelessHint() { return false; } } private static class StatefulBehavior extends Behavior { private static final long serialVersionUID = 1L; @Override public boolean getStatelessHint(Component component) { return false; } } private static class StatelessCheckerQuietly extends StatelessChecker { private StatelessCheckFailureException ex; protected void fail(StatelessCheckFailureException e) { this.ex = e; } public StatelessCheckFailureException getFailureException() { return ex; } } private StatelessChecker checker; private StatelessCheckerQuietly checkerQuietly; private WicketTester tester; @Before public void setUp() { tester = new WicketTester(); checker = new StatelessChecker(); checkerQuietly = new StatelessCheckerQuietly(); } @After public void tearDown() { tester.destroy(); } @Test public void testNonBookmarkablePage() { try { startNonBookmarkablePage(checker); fail("Expected tester.startPage() to fail with StatelessCheckFailureException"); } catch (StatelessCheckFailureException ex) { assertNonBookmarkablePage(ex); } } @Test public void testNonBookmarkablePageQuietly() { startNonBookmarkablePage(checkerQuietly); StatelessCheckFailureException ex = checkerQuietly.getFailureException(); assertNonBookmarkablePage(ex); } private void startNonBookmarkablePage(StatelessChecker checker) { tester.getApplication().getComponentPostOnBeforeRenderListeners().add(checker); tester.startPage(StatelessPage.class); } private void assertNonBookmarkablePage(StatelessCheckFailureException ex) { assertEquals("'[Page class = org.apache.wicket.devutils.stateless.StatelessCheckerTest$StatelessPage, id = 0, render count = 1]' claims to be stateless but isn't. Offending component: [TestLink [Component id = testPage]]", ex.getMessage()); assertEquals(StatelessPage.class, ex.getComponent().getClass()); } @Test public void testStatefulBehaviors() { try { startComponentInPage(checker, new StatelessLabel("foo").add(new StatefulBehavior())); fail("Expected tester.startComponentInPage() to fail with StatelessCheckFailureException"); } catch (StatelessCheckFailureException ex) { assertStatefulBehaviors(ex); } } @Test public void testStatefulBehaviorsQuietly() { startComponentInPage(checkerQuietly, new StatelessLabel("foo").add(new StatefulBehavior())); StatelessCheckFailureException ex = checkerQuietly.getFailureException(); assertStatefulBehaviors(ex); } private void startComponentInPage(StatelessChecker checker, Component foo) { tester.getApplication().getComponentPostOnBeforeRenderListeners().add(checker); tester.startComponentInPage(foo); } private void assertStatefulBehaviors(StatelessCheckFailureException ex) { assertEquals("'[Component id = foo]' claims to be stateless but isn't. Stateful behaviors: org.apache.wicket.devutils.stateless.StatelessCheckerTest$StatefulBehavior", ex.getMessage()); assertEquals(StatelessLabel.class, ex.getComponent().getClass()); } @Test public void testPositive() { startComponentInPage(checker, new StatelessLabel("foo")); } @Test public void testStatefulMarkupContainer() { try { startComponentInPage(checker, new StatefulMarkupContainer("foo")); fail("Expected tester.startComponentInPage() to fail with StatelessCheckFailureException"); } catch (StatelessCheckFailureException ex) { assertStatefulMarkupContainer(ex); } } @Test public void testStatefulMarkupContainerQuietly() { startComponentInPage(checkerQuietly, new StatefulMarkupContainer("foo")); StatelessCheckFailureException ex = checkerQuietly.getFailureException(); assertStatefulMarkupContainer(ex); } private void assertStatefulMarkupContainer(StatelessCheckFailureException ex) { assertEquals("'[StatefulMarkupContainer [Component id = foo]]' claims to be stateless but isn't. Possible reason: no stateless hint", ex.getMessage()); assertEquals(StatefulMarkupContainer.class, ex.getComponent().getClass()); } }