Repository: wicket Updated Branches: refs/heads/master e4922f1dd -> 724e4846b
Add hook method for exception handling to StatelessChecker * Add hook method * Add test case to check behavior of hook method Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/a787796c Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/a787796c Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/a787796c Branch: refs/heads/master Commit: a787796c74b2234f262ab840299a4142fdd91236 Parents: f7a6690 Author: kensakurai <[email protected]> Authored: Thu Jan 26 02:29:08 2017 +0900 Committer: kensakurai <[email protected]> Committed: Thu Jan 26 02:29:08 2017 +0900 ---------------------------------------------------------------------- .../devutils/stateless/StatelessChecker.java | 71 ++++++++++++++--- .../stateless/StatelessCheckerTest.java | 81 ++++++++++++++++++-- 2 files changed, 135 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/a787796c/wicket-devutils/src/main/java/org/apache/wicket/devutils/stateless/StatelessChecker.java ---------------------------------------------------------------------- diff --git a/wicket-devutils/src/main/java/org/apache/wicket/devutils/stateless/StatelessChecker.java b/wicket-devutils/src/main/java/org/apache/wicket/devutils/stateless/StatelessChecker.java index ac115c2..9b23cc2 100644 --- a/wicket-devutils/src/main/java/org/apache/wicket/devutils/stateless/StatelessChecker.java +++ b/wicket-devutils/src/main/java/org/apache/wicket/devutils/stateless/StatelessChecker.java @@ -31,10 +31,10 @@ import org.apache.wicket.util.visit.IVisitor; * stateless. This is a utility that is intended for use primarily during development. If you add an * instance of this class to your application, it will check all components or pages marked with the * <tt>StatelessComponent</tt> annotation to make sure that they are stateless as you intended. - * + * * This is useful when trying to maintain stateless pages since it is very easy to inadvertently add * a component to a page that internally uses stateful links, etc. - * + * * @author Marat Radchenko * @see StatelessComponent */ @@ -43,7 +43,7 @@ public class StatelessChecker implements IComponentOnBeforeRenderListener /** * Returns <code>true</code> if checker must check given component, <code>false</code> * otherwise. - * + * * @param component * component to check. * @return <code>true</code> if checker must check given component. @@ -53,6 +53,58 @@ public class StatelessChecker implements IComponentOnBeforeRenderListener final StatelessComponent ann = component.getClass().getAnnotation(StatelessComponent.class); return (ann != null) && ann.enabled(); } + /** + * The given component claims to be stateless but isn't. + * + * @param component component failing stateless check + * @param reason explaining reason + */ + protected void fail(Component component, String reason) + { + throw new IllegalArgumentException(getMessage(component) + reason); + } + + /** + * The given page claims to be stateless but isn't. + * + * @param page page failing stateless check + * @param reason explaining reason + */ + protected void failPage(Page page, String reason) + { + fail(page, reason); + } + + /** + * The given markupContainer claims to be stateless but isn't. + * + * @param markupContainer MarkupContainer failing stateless check + * @param reason explaining reason + */ + protected void failMarkupContainer(MarkupContainer markupContainer, String reason) + { + fail(markupContainer, reason); + } + /** + * The given component claims to be stateless but isn't, because the holding behaviors are stateful. + * + * @param component component failing stateless check + * @param reason explaining reason + */ + protected void failBehaviors(Component component, String reason) + { + throw new IllegalStateException(getMessage(component) + reason); + } + /** + * return the message from the component + * + * @param component component failing stateless check + * @return message + */ + private String getMessage(Component component) + { + return "'" + component + "' claims to be stateless but isn't. "; + } /** * @see org.apache.wicket.application.IComponentOnBeforeRenderListener#onBeforeRender(org.apache.wicket.Component) @@ -91,7 +143,6 @@ public class StatelessChecker implements IComponentOnBeforeRenderListener } }; - final String msg = "'" + component + "' claims to be stateless but isn't."; if (component.isStateless() == false) { StringList statefulBehaviors = new StringList(); @@ -111,16 +162,17 @@ public class StatelessChecker implements IComponentOnBeforeRenderListener { reason = " Stateful behaviors: " + statefulBehaviors.join(); } - throw new IllegalStateException(msg + reason); + failBehaviors(component, reason); } if (component instanceof MarkupContainer) { + MarkupContainer container = ((MarkupContainer)component); // Traverse children - final Object o = ((MarkupContainer)component).visitChildren(visitor); + final Object o = container.visitChildren(visitor); if (o != null) { - throw new IllegalArgumentException(msg + " Offending component: " + o); + failMarkupContainer(container, " Offending component: " + o); } } @@ -129,12 +181,11 @@ public class StatelessChecker implements IComponentOnBeforeRenderListener final Page p = (Page)component; if (!p.isBookmarkable()) { - throw new IllegalArgumentException(msg + - " Only bookmarkable pages can be stateless"); + failPage(p, " Only bookmarkable pages can be stateless"); } if (!p.isPageStateless()) { - throw new IllegalArgumentException(msg + " for unknown reason"); + failPage(p, " for unknown reason"); } } } http://git-wip-us.apache.org/repos/asf/wicket/blob/a787796c/wicket-devutils/src/test/java/org/apache/wicket/devutils/stateless/StatelessCheckerTest.java ---------------------------------------------------------------------- diff --git a/wicket-devutils/src/test/java/org/apache/wicket/devutils/stateless/StatelessCheckerTest.java b/wicket-devutils/src/test/java/org/apache/wicket/devutils/stateless/StatelessCheckerTest.java index c02f936..707e7e0 100644 --- a/wicket-devutils/src/test/java/org/apache/wicket/devutils/stateless/StatelessCheckerTest.java +++ b/wicket-devutils/src/test/java/org/apache/wicket/devutils/stateless/StatelessCheckerTest.java @@ -16,6 +16,9 @@ */ package org.apache.wicket.devutils.stateless; +import org.apache.wicket.Component; +import org.apache.wicket.WicketRuntimeException; +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; @@ -52,7 +55,29 @@ public class StatelessCheckerTest extends Assert } } + private static class StatefulBehavior extends Behavior + { + private static final long serialVersionUID = 1L; + + @Override + public boolean getStatelessHint(Component component) + { + return false; + } + } + private final StatelessChecker checker = new StatelessChecker(); + private final StatelessChecker checkerQuietly = new StatelessChecker() { + protected void fail(Component component, String reason) + { + // Do Nothing... + } + protected void failBehaviors(Component component, String reason) { + // Do Nothing... + } + + }; + private WicketTester tester; /** @@ -76,6 +101,54 @@ public class StatelessCheckerTest extends Assert @Test public void testNonBookmarkablePage() { + boolean hit = isHitBookmarkablePage(checker); + assertTrue("Expected exception", hit); + } + + @Test + public void testNonBookmarkablePageQuietly() + { + boolean hit = isHitBookmarkablePage(checkerQuietly); + assertFalse("Expected exception", hit); + } + + @Test + public void testStatefulBehaviors() + { + boolean hit = isHitBehaviors(checker); + assertTrue("Expected exception", hit); + } + @Test + public void testStatefulBehaviorsQuietly() + { + boolean hit = isHitBehaviors(checkerQuietly); + assertFalse("Expected exception", hit); + } + + @Test + public void testPositive() + { + tester.getApplication().getComponentPostOnBeforeRenderListeners().add(checker); + tester.startComponentInPage(new StatelessLabel("foo")); + } + + private boolean isHitBehaviors(StatelessChecker checker) { + boolean hit = false; + try + { + tester.getApplication().getComponentPostOnBeforeRenderListeners().add(checker); + tester.startComponentInPage(new StatelessLabel("foo").add(new StatefulBehavior())); + } + catch (WicketRuntimeException ex) + { + if(ex.getCause() instanceof IllegalStateException) { + hit = true; + } + } + return hit; + } + + private boolean isHitBookmarkablePage(StatelessChecker checker) { boolean hit = false; try { @@ -86,13 +159,7 @@ public class StatelessCheckerTest extends Assert { hit = true; } - assertTrue("Expected exception", hit); + return hit; } - @Test - public void testPositive() - { - tester.getApplication().getComponentPostOnBeforeRenderListeners().add(checker); - tester.startComponentInPage(new StatelessLabel("foo")); - } }
