You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2023/03/18 14:47:55 UTC
[causeway] 04/07: CAUSEWAY-1840 : adds CausewayIntegrationGwtAbstract and updates docs
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 7113cb2d262cf26e0e9b5566366c2396451272d0
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sat Mar 18 14:15:35 2023 +0000
CAUSEWAY-1840 : adds CausewayIntegrationGwtAbstract and updates docs
---
.../interactions-commands-and-executions.adoc | 1 +
...CausewayIntegrationGwtAbstractWithFixtures.java | 72 ++++++++++
.../adoc/modules/integtestsupport/pages/about.adoc | 9 +-
.../applib/CausewayIntegrationGwtAbstract.java | 151 +++++++++++++++++++++
.../applib/CausewayIntegrationTestAbstract.java | 108 +--------------
...tract.java => CausewayIntegrationTestBase.java} | 37 +----
6 files changed, 235 insertions(+), 143 deletions(-)
diff --git a/core/interaction/src/main/adoc/modules/interaction/pages/interactions-commands-and-executions.adoc b/core/interaction/src/main/adoc/modules/interaction/pages/interactions-commands-and-executions.adoc
index 24c5bf2bde..f4d031247c 100644
--- a/core/interaction/src/main/adoc/modules/interaction/pages/interactions-commands-and-executions.adoc
+++ b/core/interaction/src/main/adoc/modules/interaction/pages/interactions-commands-and-executions.adoc
@@ -16,6 +16,7 @@ One use case is for "headless" execution of background commands, eg as scheduled
Another important use case is within testing.
The xref:refguide:testing:index/integtestsupport/applib/CausewayInteractionHandler.adoc[] JUnit 5 extension takes responsibility for wrapping each test with an `Interaction` (taking account any xref:refguide:testing:index/integtestsupport/applib/annotation/InteractAs.adoc[] annotation if present).
The xref:refguide:testing:index/integtestsupport/applib/CausewayIntegrationTestAbstract.adoc[] is provided as a convenient superclass for integration tests, and is already annotated with the `CausewayInteractionHandler` extension.
+(Alternatively, xref:refguide:testing:index/integtestsupport/applib/CausewayIntegrationGwtAbstract.adoc[] is _not_ annotated with the handler; instead it provides `given(...)`, `when(...)` and `then(...)` methods that each execute the provided `Runnable`/`Callable` within the context of its own `Interaction`.
Integration tests can also simulate multiple interactions (HTTP requests) within a single test using xref:refguide:applib:index/services/iactnlayer/InteractionService.adoc#nextInteraction_[InteractionService#nextInteraction].
When called, any state changes made in the previous `Interaction` will be committed, and any references to entities should be either discarded or else be re-retrieved in the next `Interaction`.
diff --git a/testing/fixtures/applib/src/main/java/org/apache/causeway/testing/fixtures/applib/CausewayIntegrationGwtAbstractWithFixtures.java b/testing/fixtures/applib/src/main/java/org/apache/causeway/testing/fixtures/applib/CausewayIntegrationGwtAbstractWithFixtures.java
new file mode 100644
index 0000000000..a320b7f270
--- /dev/null
+++ b/testing/fixtures/applib/src/main/java/org/apache/causeway/testing/fixtures/applib/CausewayIntegrationGwtAbstractWithFixtures.java
@@ -0,0 +1,72 @@
+/*
+ * 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.causeway.testing.fixtures.applib;
+
+import javax.inject.Inject;
+
+import org.apache.causeway.testing.fixtures.applib.fixturescripts.FixtureScript;
+import org.apache.causeway.testing.fixtures.applib.fixturescripts.FixtureScripts;
+import org.apache.causeway.testing.fixtures.applib.modules.ModuleWithFixturesService;
+import org.apache.causeway.testing.fixtures.applib.personas.BuilderScriptAbstract;
+import org.apache.causeway.testing.fixtures.applib.personas.PersonaWithBuilderScript;
+import org.apache.causeway.testing.integtestsupport.applib.CausewayIntegrationGwtAbstract;
+import org.apache.causeway.testing.integtestsupport.applib.CausewayIntegrationTestAbstract;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+
+/**
+ * @since 2.x {@index}
+ */
+public abstract class CausewayIntegrationGwtAbstractWithFixtures extends CausewayIntegrationGwtAbstract {
+
+ protected void run(final FixtureScript... fixtureScriptList) {
+ this.fixtureScripts.run(fixtureScriptList);
+ }
+
+ protected <T> T runBuilder(final BuilderScriptAbstract<T> fixtureScript) {
+ return this.fixtureScripts.runBuilder(fixtureScript);
+ }
+
+ protected void runPersonas(
+ @SuppressWarnings("unchecked") final PersonaWithBuilderScript<?, ? extends BuilderScriptAbstract<?>>... personaScripts) {
+ this.fixtureScripts.runPersonas(personaScripts);
+ }
+
+ protected <T> T runPersona(final PersonaWithBuilderScript<T, ? extends BuilderScriptAbstract<T>> personaScript) {
+ return this.fixtureScripts.runPersona(personaScript);
+ }
+
+ // -- DEPENDENCIES
+
+ @BeforeEach
+ protected void setupRefDataFixtures() {
+ fixtureScripts.run(moduleWithFixturesService.getRefDataSetupFixture());
+ }
+
+ @AfterEach
+ protected void tearDownFixtures() {
+ fixtureScripts.run(moduleWithFixturesService.getTeardownFixture());
+ }
+
+ @Inject protected ModuleWithFixturesService moduleWithFixturesService;
+
+ @Inject protected FixtureScripts fixtureScripts;
+
+
+}
diff --git a/testing/integtestsupport/adoc/modules/integtestsupport/pages/about.adoc b/testing/integtestsupport/adoc/modules/integtestsupport/pages/about.adoc
index da7acc30c9..fa6a19b38d 100644
--- a/testing/integtestsupport/adoc/modules/integtestsupport/pages/about.adoc
+++ b/testing/integtestsupport/adoc/modules/integtestsupport/pages/about.adoc
@@ -406,12 +406,11 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
Some of the methods being called here are inherited from the superclass, so let's look at that next.
-== CausewayIntegrationTestAbstract
+== CausewayIntegrationTestAbstract / CausewayIntegrationGwtAbstract
-For convenience the framework provides the `CausewayIntegrationTestAbstract` as a base class for integration tests.
+For convenience the framework provides the xref:refguide:testing:index/integtestsupport/applib/CausewayIntegrationTestAbstract.adoc[] and xref:refguide:testing:index/integtestsupport/applib/CausewayIntegrationGwtAbstract.adoc[] classes, either of which can be used as a base class for integration tests.
-
-This is the class that provides the `wrap(...)` method (as see in the xref:about.adoc#typical-usage[previous section]).
+These classes that provides the `wrap(...)` method (as see in the xref:about.adoc#typical-usage[previous section]).
It also provides a number of other convenience methods:
* `wrap()` - as just mentioned.
@@ -457,8 +456,6 @@ This is discussed further xref:about.adoc#wrapper-factory[below].
for more control over transactions
-The class also defines (as a nested static class) the `InteractionSupport` as a domain service.
-If ``@Import``ed into the integration test's "app manifest", this ensures that any xref:refguide:applib:index/services/command/Command.adoc[Command]s that are raised as the result of interactions through the wrapper factory are setup correctly.
[#wrapper-factory]
diff --git a/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationGwtAbstract.java b/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationGwtAbstract.java
new file mode 100644
index 0000000000..dd7bf54676
--- /dev/null
+++ b/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationGwtAbstract.java
@@ -0,0 +1,151 @@
+/*
+ * 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.causeway.testing.integtestsupport.applib;
+
+import java.util.concurrent.Callable;
+
+import org.apache.causeway.applib.services.iactnlayer.InteractionContext;
+import org.apache.causeway.commons.functional.ThrowingRunnable;
+import org.apache.causeway.commons.functional.Try;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Convenient base class to extend for integration tests.
+ *
+ * <p>
+ * Unlike {@link CausewayIntegrationTestAbstract}, this class is not {@link ExtendWith extended with} {@link CausewayInteractionHandler},
+ * which means that there is <i>no</i> {@link org.apache.causeway.applib.services.iactn.Interaction} set up implicitly.
+ * Instead the {@link #given(Callable)}, {@link #when(Callable)} and {@link #then(Callable)} (and their various overrides) can be used
+ * with the provided {@link Callable} or {@link ThrowingRunnable} being called within its own {@link org.apache.causeway.applib.services.iactn.Interaction}.
+ * </p>
+ *
+ * <p>
+ * Note that this means that references to entities must be re-retrieved within each given/when/then phase.
+ * {@link org.apache.causeway.applib.services.bookmark.Bookmark}s and the {@link org.apache.causeway.applib.services.bookmark.BookmarkService} can be a good way to do perform this re-retrieval.
+ * </p>
+ *
+ * @since 2.0 {@index}
+ * @see CausewayIntegrationTestAbstract
+ */
+@ExtendWith({ExceptionRecognizerTranslate.class})
+public abstract class CausewayIntegrationGwtAbstract extends CausewayIntegrationTestBase {
+
+ protected void given(final ThrowingRunnable runnable) {
+ interactionService.runAnonymous(runnable);
+ }
+
+ protected <T> T given(final Callable<T> callable) {
+ return interactionService.callAnonymous(callable);
+ }
+
+ protected void given(final InteractionContext interactionContext, final ThrowingRunnable runnable) {
+ interactionService.run(interactionContext, runnable);
+ }
+
+ protected <T> T given(final InteractionContext interactionContext, final Callable<T> callable) {
+ return interactionService.call(interactionContext, callable);
+ }
+
+ protected Try<Void> givenAndCatch(final ThrowingRunnable runnable) {
+ return interactionService.runAnonymousAndCatch(runnable);
+ }
+
+ protected <T> Try<T> givenAndCatch(final Callable<T> callable) {
+ return interactionService.callAnonymousAndCatch(callable);
+ }
+
+ protected Try<Void> givenAndCatch(final InteractionContext interactionContext, final ThrowingRunnable runnable) {
+ return interactionService.runAndCatch(interactionContext, runnable);
+ }
+
+ protected <T> Try<T> givenAndCatch(final InteractionContext interactionContext, final Callable<T> callable) {
+ return interactionService.callAndCatch(interactionContext, callable);
+ }
+
+
+
+ protected void when(final ThrowingRunnable runnable) {
+ interactionService.runAnonymous(runnable);
+ }
+
+ protected <T> T when(final Callable<T> callable) {
+ return interactionService.callAnonymous(callable);
+ }
+
+ protected void when(final InteractionContext interactionContext, final ThrowingRunnable runnable) {
+ interactionService.run(interactionContext, runnable);
+ }
+
+ protected <T> T when(final InteractionContext interactionContext, final Callable<T> callable) {
+ return interactionService.call(interactionContext, callable);
+ }
+
+ protected Try<Void> whenAndCatch(final ThrowingRunnable runnable) {
+ return interactionService.runAnonymousAndCatch(runnable);
+ }
+
+ protected <T> Try<T> whenAndCatch(final Callable<T> callable) {
+ return interactionService.callAnonymousAndCatch(callable);
+ }
+
+ protected Try<Void> whenAndCatch(final InteractionContext interactionContext, final ThrowingRunnable runnable) {
+ return interactionService.runAndCatch(interactionContext, runnable);
+ }
+
+ protected <T> Try<T> whenAndCatch(final InteractionContext interactionContext, final Callable<T> callable) {
+ return interactionService.callAndCatch(interactionContext, callable);
+ }
+
+
+
+ protected void then(final ThrowingRunnable runnable) {
+ interactionService.runAnonymous(runnable);
+ }
+
+ protected <T> T then(final Callable<T> callable) {
+ return interactionService.callAnonymous(callable);
+ }
+
+ protected void then(final InteractionContext interactionContext, final ThrowingRunnable runnable) {
+ interactionService.run(interactionContext, runnable);
+ }
+
+ protected <T> T then(final InteractionContext interactionContext, final Callable<T> callable) {
+ return interactionService.call(interactionContext, callable);
+ }
+
+ protected Try<Void> thenAndCatch(final ThrowingRunnable runnable) {
+ return interactionService.runAnonymousAndCatch(runnable);
+ }
+
+ protected <T> Try<T> thenAndCatch(final Callable<T> callable) {
+ return interactionService.callAnonymousAndCatch(callable);
+ }
+
+ protected Try<Void> thenAndCatch(final InteractionContext interactionContext, final ThrowingRunnable runnable) {
+ return interactionService.runAndCatch(interactionContext, runnable);
+ }
+
+ protected <T> Try<T> thenAndCatch(final InteractionContext interactionContext, final Callable<T> callable) {
+ return interactionService.callAndCatch(interactionContext, callable);
+ }
+
+
+
+}
diff --git a/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestAbstract.java b/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestAbstract.java
index 01e90f1d49..3ae8d51866 100644
--- a/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestAbstract.java
+++ b/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestAbstract.java
@@ -18,29 +18,7 @@
*/
package org.apache.causeway.testing.integtestsupport.applib;
-import javax.inject.Inject;
-import javax.inject.Provider;
-
import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.stereotype.Service;
-
-import org.apache.causeway.applib.annotation.PriorityPrecedence;
-import org.apache.causeway.applib.services.command.Command;
-import org.apache.causeway.applib.services.factory.FactoryService;
-import org.apache.causeway.applib.services.iactn.InteractionProvider;
-import org.apache.causeway.applib.services.inject.ServiceInjector;
-import org.apache.causeway.applib.services.metamodel.MetaModelService;
-import org.apache.causeway.applib.services.registry.ServiceRegistry;
-import org.apache.causeway.applib.services.repository.EntityState;
-import org.apache.causeway.applib.services.repository.RepositoryService;
-import org.apache.causeway.applib.services.user.UserService;
-import org.apache.causeway.applib.services.wrapper.WrapperFactory;
-import org.apache.causeway.applib.services.xactn.TransactionService;
-import org.apache.causeway.core.metamodel.objectmanager.ObjectManager;
-
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
/**
* Convenient base class to extend for integration tests.
@@ -48,90 +26,6 @@ import lombok.RequiredArgsConstructor;
* @since 2.0 {@index}
*/
@ExtendWith({ExceptionRecognizerTranslate.class, CausewayInteractionHandler.class})
-public abstract class CausewayIntegrationTestAbstract {
-
- /**
- * Hook to interact with
- * {@link org.apache.causeway.applib.services.iactn.Interaction}s and
- * therefore also {@link Command}s (currently unused).
- */
- @Service
- @javax.annotation.Priority(PriorityPrecedence.MIDPOINT)
- @RequiredArgsConstructor(onConstructor_ = {@Inject})
- public static class InteractionSupport {
-
- @SuppressWarnings("unused")
- private final Provider<InteractionProvider> interactionProviderProvider;
-
- }
-
- /**
- * Convenience method, simply delegates to {@link WrapperFactory#wrap(Object)}
- */
- protected <T> T wrap(final T obj) {
- return wrapperFactory.wrap(obj);
- }
-
- /**
- * Convenience method, synonym of {@link #wrap(Object)}
- */
- protected <T> T w(final T obj) {
- return wrap(obj);
- }
-
- /**
- * Convenience method, simply delegates to {@link WrapperFactory#wrapMixin(Class, Object)}.
- */
- protected <T> T wrapMixin(final Class<T> mixinClass, final Object mixedIn) {
- return wrapperFactory.wrapMixin(mixinClass, mixedIn);
- }
-
- /**
- * Convenience method, synonym for {@link #wrapMixin(Class, Object)}.
- */
- protected <T> T wm(final Class<T> mixinClass, final Object mixedIn) {
- return wrapMixin(mixinClass, mixedIn);
- }
-
- /**
- * Convenience method, simply delegates to {@link FactoryService#mixin(Class, Object)}.
- */
- protected <T> T mixin(final Class<T> mixinClass, final Object mixedIn) {
- return factoryService.mixin(mixinClass, mixedIn);
- }
-
- /**
- * Convenience method, synonym for {@link #mixin(Class, Object)}.
- */
- protected <T> T m(final Class<T> mixinClass, final Object mixedIn) {
- return factoryService.mixin(mixinClass, mixedIn);
- }
-
- /**
- * For convenience of subclasses, remove some boilerplate
- */
- protected <T> T unwrap(final T obj) {
- return wrapperFactory.unwrap(obj);
- }
-
- /**
- * Get the current {@link EntityState} of given pojo.
- */
- protected EntityState entityState(final Object obj) {
- return objectManager.adapt(obj).getEntityState();
- }
-
- // -- DEPENDENCIES
-
- @Inject protected ServiceRegistry serviceRegistry;
- @Inject protected MetaModelService metaModelService;
- @Inject protected FactoryService factoryService;
- @Inject protected RepositoryService repositoryService;
- @Inject protected ServiceInjector serviceInjector;
- @Inject protected UserService userService;
- @Inject protected WrapperFactory wrapperFactory;
- @Inject protected TransactionService transactionService;
+public abstract class CausewayIntegrationTestAbstract extends CausewayIntegrationTestBase {
- // for internal framework debugging
- @Inject private ObjectManager objectManager;
}
diff --git a/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestAbstract.java b/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestBase.java
similarity index 77%
copy from testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestAbstract.java
copy to testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestBase.java
index 01e90f1d49..7e59bceedf 100644
--- a/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestAbstract.java
+++ b/testing/integtestsupport/applib/src/main/java/org/apache/causeway/testing/integtestsupport/applib/CausewayIntegrationTestBase.java
@@ -19,15 +19,9 @@
package org.apache.causeway.testing.integtestsupport.applib;
import javax.inject.Inject;
-import javax.inject.Provider;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.stereotype.Service;
-
-import org.apache.causeway.applib.annotation.PriorityPrecedence;
-import org.apache.causeway.applib.services.command.Command;
import org.apache.causeway.applib.services.factory.FactoryService;
-import org.apache.causeway.applib.services.iactn.InteractionProvider;
+import org.apache.causeway.applib.services.iactnlayer.InteractionService;
import org.apache.causeway.applib.services.inject.ServiceInjector;
import org.apache.causeway.applib.services.metamodel.MetaModelService;
import org.apache.causeway.applib.services.registry.ServiceRegistry;
@@ -38,32 +32,12 @@ import org.apache.causeway.applib.services.wrapper.WrapperFactory;
import org.apache.causeway.applib.services.xactn.TransactionService;
import org.apache.causeway.core.metamodel.objectmanager.ObjectManager;
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
/**
- * Convenient base class to extend for integration tests.
- *
- * @since 2.0 {@index}
+ * Not public API, but factors out commonality of {@link CausewayIntegrationTestAbstract} and
+ * {@link CausewayIntegrationGwtAbstract}.
*/
-@ExtendWith({ExceptionRecognizerTranslate.class, CausewayInteractionHandler.class})
-public abstract class CausewayIntegrationTestAbstract {
-
- /**
- * Hook to interact with
- * {@link org.apache.causeway.applib.services.iactn.Interaction}s and
- * therefore also {@link Command}s (currently unused).
- */
- @Service
- @javax.annotation.Priority(PriorityPrecedence.MIDPOINT)
- @RequiredArgsConstructor(onConstructor_ = {@Inject})
- public static class InteractionSupport {
-
- @SuppressWarnings("unused")
- private final Provider<InteractionProvider> interactionProviderProvider;
+abstract class CausewayIntegrationTestBase {
- }
/**
* Convenience method, simply delegates to {@link WrapperFactory#wrap(Object)}
@@ -114,6 +88,7 @@ public abstract class CausewayIntegrationTestAbstract {
return wrapperFactory.unwrap(obj);
}
+
/**
* Get the current {@link EntityState} of given pojo.
*/
@@ -121,8 +96,10 @@ public abstract class CausewayIntegrationTestAbstract {
return objectManager.adapt(obj).getEntityState();
}
+
// -- DEPENDENCIES
+ @Inject protected InteractionService interactionService;
@Inject protected ServiceRegistry serviceRegistry;
@Inject protected MetaModelService metaModelService;
@Inject protected FactoryService factoryService;