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;