You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2023/03/15 08:19:58 UTC

[wicket] branch master updated: [WICKET-7030] Add Convenience Methods to BaseWicketTester (#555)

This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/master by this push:
     new fb1f739342 [WICKET-7030] Add Convenience Methods to BaseWicketTester (#555)
fb1f739342 is described below

commit fb1f73934240df1bbe0188242938d61a6a590992
Author: Johannes Renoth <re...@users.noreply.github.com>
AuthorDate: Wed Mar 15 09:19:51 2023 +0100

    [WICKET-7030] Add Convenience Methods to BaseWicketTester (#555)
    
    * - Add getAllComponentsFromLastRenderedPageByWicketId and getFirstComponentFromLastRenderedPageByWicketId to BaseWicketTester
    
    * - Add getAllComponentsFromLastRenderedPageByWicketId and getFirstComponentFromLastRenderedPageByWicketId to BaseWicketTester
    
    * License
    
    * WICKET-7030
    - Javadoc
    - Fix edge cases
    
    ---------
    
    Co-authored-by: renoth <jo...@renoth.dev>
---
 .../wicket/util/tester/BaseWicketTester.java       |  57 ++++++
 .../wicket/util/tester/BaseWicketTesterTest.java   | 205 +++++++++++++++++++++
 .../wicket/util/tester/DemoPanel$DemoPanelB.html   |   9 +
 .../org/apache/wicket/util/tester/DemoPanel.html   |  12 ++
 .../org/apache/wicket/util/tester/DemoPanel.java   |  60 ++++++
 .../injection/bytebuddy/ParallelInjectionTest.java |  11 +-
 6 files changed, 347 insertions(+), 7 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
index 4f6f33e486..b9ada8c0db 100644
--- a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
+++ b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
@@ -32,6 +32,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.UUID;
 import java.util.regex.Pattern;
@@ -1576,6 +1577,62 @@ public class BaseWicketTester
 		return getComponentFromLastRenderedPage(path, true);
 	}
 
+	/**
+	 * Returns the first {@link Component} (breadth-first search) matching the given Wicket-ID. If no such
+	 * {@link Component} exists it returns {@link Optional#empty()}
+	 *
+	 * @param wicketId
+	 *            the Wicket-ID of the {@link Component} to be found
+	 * @return Optional of the component, {@link Optional#empty()} if no matching component can be found or wicketId is
+	 *         null or blank.
+	 */
+	public Optional<Component> getFirstComponentByWicketId(String wicketId) {
+		if (wicketId == null || wicketId.isBlank()) {
+			return Optional.empty();
+		}
+
+		if (getLastRenderedPage() != null && componentInPage != null) {
+			Component component = getLastRenderedPage().visitChildren((c, visit) -> {
+				if (c.getId().equals(wicketId)) {
+					visit.stop(c);
+				}
+			});
+
+			return Optional.ofNullable(component);
+		}
+
+		return Optional.empty();
+	}
+
+	/**
+	 * Returns a {@link List} of all {@link Component}s matching the given Wicket-ID. Returns an empty list if no such
+	 * component can be found or the Wicket-ID is null.
+	 *
+	 * @param wicketId
+	 *            the Wicket-ID of the components to be found
+	 * @return A list of all {@link Component}s that have the given Wicket-ID, an empty List if no such component can be
+	 *         found. Returns an empty List of wicketId is null or blank.
+	 */
+	public List<Component> getAllComponentsByWicketId(String wicketId) {
+		var result = new ArrayList<Component>();
+
+		if (wicketId == null || wicketId.isBlank()) {
+			return result;
+		}
+
+		if (getLastRenderedPage() != null && componentInPage != null) {
+			getLastRenderedPage().visitChildren((c, visit) -> {
+				if (c.getId().equals(wicketId)) {
+					result.add(c);
+				}
+			});
+		}
+
+		log.debug("Found {} Components with ID '{}'", result.size(), wicketId);
+
+		return result;
+	}
+
 	/**
 	 * assert the text of <code>Label</code> component.
 	 *
diff --git a/wicket-core/src/test/java/org/apache/wicket/util/tester/BaseWicketTesterTest.java b/wicket-core/src/test/java/org/apache/wicket/util/tester/BaseWicketTesterTest.java
new file mode 100644
index 0000000000..12b52f3423
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/util/tester/BaseWicketTesterTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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.util.tester;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.mock.MockApplication;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class BaseWicketTesterTest {
+
+	private BaseWicketTester tester;
+
+	@BeforeEach
+	public void before() {
+		tester = new BaseWicketTester(new MockApplication());
+	}
+
+	@Test
+	void ggetFirstComponentFromLastRenderedPageByWicketId_whenCallPrematurely_returnEmptyOptional() {
+		// Arrange
+		var cut = new DemoPanel("id");
+
+		// Act
+		var label = tester.getFirstComponentByWicketId("label");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(label).isEmpty();
+		});
+	}
+
+	@Test
+	void getFirstComponentFromLastRenderedPageByWicketId_whenComponentPresent_returnComponent() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var label = tester.getFirstComponentByWicketId("label");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(label).isPresent();
+			sa.assertThat(label.get().getPath()).isEqualTo("0:id:label");
+		});
+	}
+
+	@Test
+	void getFirstComponentFromLastRenderedPageByWicketId_whenComponentNotPresent_returnEmptyOptional() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var label = tester.getFirstComponentByWicketId("asdf");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(label).isEmpty();
+		});
+	}
+
+	@Test
+	void getFirstComponentFromLastRenderedPageByWicketId_whenWicketIdNull_returnEmptyOptional() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var label = tester.getFirstComponentByWicketId(null);
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(label).isEmpty();
+		});
+	}
+
+	@Test
+	void getFirstComponentFromLastRenderedPageByWicketId_whenWicketIdBlank_returnEmptyOptional() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var label = tester.getFirstComponentByWicketId(" ");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(label).isEmpty();
+		});
+	}
+
+	@Test
+	void getAllComponentsFromLastRenderedPageByWicketId_whenCallPrematurely_returnEmptyList() {
+		// Arrange
+		var cut = new DemoPanel("id");
+
+		// Act
+		var components = tester.getAllComponentsByWicketId("label");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(components).isEmpty();
+		});
+	}
+
+	@Test
+	void getAllComponentsFromLastRenderedPageByWicketId_whenMultipleComponentPresent_returnComponentList() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var components = tester.getAllComponentsByWicketId("label");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(components).hasSize(2);
+			sa.assertThat(components).extracting(Component::getPath)
+					.containsExactly("0:id:label", "0:id:otherPanel:label");
+		});
+	}
+
+	@Test
+	void getAllComponentsFromLastRenderedPageByWicketId_whenMultipleComponentPresent2_returnComponentList() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var components = tester.getAllComponentsByWicketId("content");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(components).hasSize(4);
+			sa.assertThat(components).extracting(Component::getPath).containsExactly(
+					"0:id:repeater:0:content",
+					"0:id:repeater:1:content",
+					"0:id:repeater:2:content",
+					"0:id:repeater:3:content");
+		});
+	}
+
+	@Test
+	void getAllComponentsFromLastRenderedPageByWicketId_whenNoComponentPresent2_returnEmptyList() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var components = tester.getAllComponentsByWicketId("asdf");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(components).isEmpty();
+		});
+	}
+
+	@Test
+	void getAllComponentsFromLastRenderedPageByWicketId_whenWicketIdNull_returnEmptyList() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var components = tester.getAllComponentsByWicketId(null);
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(components).isEmpty();
+		});
+	}
+
+	@Test
+	void getAllComponentsFromLastRenderedPageByWicketId_whenWicketIdBlank_returnEmptyList() {
+		// Arrange
+		var cut = new DemoPanel("id");
+		tester.startComponentInPage(cut);
+
+		// Act
+		var components = tester.getAllComponentsByWicketId("");
+
+		// Assert
+		SoftAssertions.assertSoftly(sa -> {
+			sa.assertThat(components).isEmpty();
+		});
+	}
+
+}
\ No newline at end of file
diff --git a/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel$DemoPanelB.html b/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel$DemoPanelB.html
new file mode 100644
index 0000000000..46551163a2
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel$DemoPanelB.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+<body>
+	<wicket:panel>
+		<span wicket:id="innerLabel"></span>
+		<span wicket:id="label"></span>
+	</wicket:panel>
+</body>
+</html>
\ No newline at end of file
diff --git a/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel.html b/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel.html
new file mode 100644
index 0000000000..340805e9d4
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+<body>
+	<wicket:panel>
+		<span wicket:id="label"></span>
+		<ul wicket:id="repeater">
+			<li wicket:id="content"></li>
+		</ul>
+		<div wicket:id="otherPanel"></div>
+	</wicket:panel>
+</body>
+</html>
\ No newline at end of file
diff --git a/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel.java b/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel.java
new file mode 100644
index 0000000000..efcdcef3a2
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/util/tester/DemoPanel.java
@@ -0,0 +1,60 @@
+/*
+ * 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.util.tester;
+
+import java.util.List;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.Model;
+
+public class DemoPanel extends Panel {
+	public DemoPanel(String id) {
+		super(id);
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
+
+		add(new Label("label", () -> "Label"));
+		add(new ListView<>("repeater", List.of("AAA", "BBB", "CCC", "DDD")) {
+			@Override
+			protected void populateItem(ListItem<String> item) {
+				item.add(new Label("content", item.getModel()));
+			}
+		});
+		add(new DemoPanelB("otherPanel"));
+	}
+
+	private class DemoPanelB extends Panel {
+		public DemoPanelB(String id) {
+			super(id);
+		}
+
+		@Override
+		protected void onInitialize() {
+			super.onInitialize();
+
+			add(new Label("innerLabel", () -> "Inner Label"));
+			add(new Label("label", () -> "Inner Label with same Wicket ID"));
+		}
+	}
+}
diff --git a/wicket-spring/src/test/java/org/apache/wicket/spring/injection/bytebuddy/ParallelInjectionTest.java b/wicket-spring/src/test/java/org/apache/wicket/spring/injection/bytebuddy/ParallelInjectionTest.java
index 9cb7eff5ce..3de18cdb08 100644
--- a/wicket-spring/src/test/java/org/apache/wicket/spring/injection/bytebuddy/ParallelInjectionTest.java
+++ b/wicket-spring/src/test/java/org/apache/wicket/spring/injection/bytebuddy/ParallelInjectionTest.java
@@ -110,7 +110,7 @@ public class ParallelInjectionTest implements ApplicationContextAware {
     }
 
     void runInjection(int nThreads) throws InterruptedException {
-                // Arrange
+        // Arrange
         var tester = new WicketTester(createPortalApplication());
         ExecutorService executor = Executors.newFixedThreadPool(nThreads);
 
@@ -136,17 +136,14 @@ public class ParallelInjectionTest implements ApplicationContextAware {
                 throw new RuntimeException("A problem occurred", e);
             }
         });
+
+        // No Assert, we expect no Exception
     }
 
     private WebApplication createPortalApplication() {
-        LOG.debug("Erstelle MockServletContext mit applicationContext");
-
-        MockServletContext mockServletContext = new MockServletContext();
-
+        var mockServletContext = new MockServletContext();
         mockServletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
 
-        LOG.debug("Erstelle PortalApplication ...");
-
         return new WebApplication() {
             @Override
             public ServletContext getServletContext() {