You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/06/07 09:16:31 UTC

[isis] 01/02: ISIS-2717: updates docs for fixture scripts

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

danhaywood pushed a commit to branch ISIS-2717
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 4b2ca171534b457a99f4c88371dc1382b187d033
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Jun 7 08:36:20 2021 +0100

    ISIS-2717: updates docs for fixture scripts
---
 .../pages/fixture-scripts/api-and-usage.adoc       | 194 ++++++++++-----------
 .../api/FixtureScriptWithExecutionStrategy.java    |  11 +-
 .../applib/api/PersonaWithBuilderScript.java       |  15 ++
 .../fixtures/applib/api/PersonaWithFinder.java     |  22 +++
 .../testing/fixtures/applib/api/WithPrereqs.java   |  13 +-
 .../testing/fixtures/applib/api/package-info.java  |  26 ---
 .../isis/testing/fixtures/applib/clock/Clock.java  |   2 +
 .../fixtures/applib/clock/FixtureClock.java        |   2 +
 .../fixtures/applib/clock/TickingFixtureClock.java |   3 +
 .../applib/clock/fixture/TickingClockFixture.java  |   3 +
 .../applib/events/FixturesInstalledEvent.java      |   3 +
 .../applib/events/FixturesInstallingEvent.java     |   3 +
 .../fixturescripts/BuilderScriptAbstract.java      |   9 +-
 .../fixturescripts/BuilderScriptWithResult.java    |  24 ++-
 .../fixturescripts/BuilderScriptWithoutResult.java |   8 +-
 .../fixturescripts/ExecutionParametersDefault.java |   2 +-
 .../fixtures/applib/fixturespec/package-info.java  |  25 ---
 .../applib/services/FixturesLifecycleService.java  |   3 +
 18 files changed, 203 insertions(+), 165 deletions(-)

diff --git a/testing/fixtures/adoc/modules/fixtures/pages/fixture-scripts/api-and-usage.adoc b/testing/fixtures/adoc/modules/fixtures/pages/fixture-scripts/api-and-usage.adoc
index 6eb23ba..b672948 100644
--- a/testing/fixtures/adoc/modules/fixtures/pages/fixture-scripts/api-and-usage.adoc
+++ b/testing/fixtures/adoc/modules/fixtures/pages/fixture-scripts/api-and-usage.adoc
@@ -3,20 +3,52 @@
 :Notice: 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 ag [...]
 
 
-There are two main parts to using fixture scripts: the xref:refguide:testing:index/fixtures/applib/fixturescripts/FixtureScripts.adoc[FixtureScripts] domain service class, and the xref:refguide:testing:index/fixtures/applib/fixturescripts/FixtureScript.adoc[FixtureScript] view model class:
+Fixture scripts are used to set up the system into a known state, which almost always means to populate the database.
+The most common use case is for integration testing, but they are also useful while prototyping/demo'ing.
+In both cases the system is almost always running against an in-memory database, meaning that the entire state of the system needs to be setup.
+As it wouldn't be scalable to have one huge fixture script for this purpose, fixture scripts are usually organised hierarchically, with higher-level fixture scripts calling child fixture scripts that set up the
+individual parts the system (eg rows into a specific entity).
 
-* The role of the `FixtureScripts` domain service is to locate all fixture scripts from the classpath and to let them be invoked, either from an integration test/BDD spec or from the UI of your Isis app.
+Fixture scripts are usually implemented by calling the business logic of the domain application.
+This is preferable to, for example, ``INSERT``ing rows directly into database tables, because they are robust to implementation changes over time.
 
-* The role of `FixtureScript` meanwhile is to subclass for each of the scenarios that you want to define.
-You can also subclass from `FixtureScript` to create helpers; more on this below.
+Fixture scripts are implemented by subclassing from the xref:refguide:testing:index/fixtures/applib/fixturescripts/FixtureScript.adoc[FixtureScript] abstract class.
+In most cases you'll want to use one of the variants provided by the framework; these are described in more detail <<fixturescript, below>>.
 
-Let's look at `FixtureScripts` domain service in more detail first.
+Fixture scripts are executed using the  xref:refguide:testing:index/fixtures/applib/fixturescripts/FixtureScripts.adoc[FixtureScripts] domain service class.
+This provides menu actions in the UI of your application (when running in prototype mode).
+Typically it will only make sense for a small subset of the available fixture scripts to be exposed through the UI, for example those representing scenarios to be explored/demo'ed.
+The behaviour of the `FixtureScripts` domain service and the discovery of scenario fixture scripts is managed by configuration properties.
 
+Let's look at `FixtureScripts` domain service in more detail <<fixturescripts,first>>, <<fixturescript, then>> move onto exploring `FixtureScript`.
+
+[#fixturescripts]
 == `FixtureScripts`
 
 The xref:refguide:testing:index/fixtures/applib/fixturescripts/FixtureScripts.adoc[FixtureScripts] domain service.
 This is annotated to be part of on the secondary "Prototyping" menu.
 
+
+Here's how the domain service looks like in the UI:
+
+image::prototyping-menu.png[width="700px"]
+
+and here's what the `runFixtureScript` action prompt looks like:
+
+image::prompt.png[width="700px"]
+
+
+when this is executed, the resultant objects (actually, instances of FixtureResult`) are shown in the UI:
+
+image::result-list.png[width="700px"]
+
+
+The `FixtureScripts` domain service also provides the `recreateObjectsAndReturnFirst` action.
+This is a convenience, saving a few clicks: it will run a nominated fixture script and return the first object created by that fixture script.
+
+
+=== Configuration Properties
+
 The behaviour of this domain menu service can be configured using the `isis.testing.fixtures.fixture-script-specification` configuration properties.
 For example, here's the configuration used by the xref:docs:starters:simpleapp.adoc[SimpleApp] starter apps:
 
@@ -39,47 +71,26 @@ isis:
 <.> specify the fixture script class to provide as the default for the service's "run fixture script" action
 <.> if present, enables a "recreate objects and return first" action to be displayed in the UI
 
+For more details, see xref:refguide:config:sections/isis.testing.adoc#isis.testing.fixtures.fixture-scripts-specification.context-class[isis.testing.fixtures.fixture-scripts-specification] config properties in the configuration guide.
 
-Here's how the domain service looks like in the UI:
-
-image::prototyping-menu.png[width="700px"]
-
-and here's what the `runFixtureScript` action prompt looks like:
-
-image::prompt.png[width="700px"]
-
-
-when this is executed, the resultant objects (actually, instances of FixtureResult`) are shown in the UI:
-
-image::result-list.png[width="700px"]
-
-
-
-If you had defined many fixture scripts then a drop-down might become unwieldy, in which case your code would probably override the `autoComplete...())` instead:
-
-[source,java]
-----
-    @Override
-    public List<FixtureScript> autoComplete0RunFixtureScript(final @MinLength(1) String searchArg) {
-        return super.autoComplete0RunFixtureScript(searchArg);
-    }
 
-----
+=== Menubars
 
-You are free, of course, to add additional "convenience" actions into it if you wish for the most commonly used/demo'd setups ; you'll find that the xref:docs:starters:simpleapp.adoc[SimpleApp archetype] adds this additional action:
+The actions of ``FixtureScripts`` domain service are automatically placed on the "Prototyping" menu.
+This can be fine-tuned using `menubars.layout.xml`:
 
-[source,java]
+[source,xml]
+.menubars.layout.xml
 ----
-    @Action(
-            restrictTo = RestrictTo.PROTOTYPING
-    )
-    @ActionLayout(
-            cssClassFa="fa fa-sync"
-    )
-    public Object recreateObjectsAndReturnFirst() {
-        final List<FixtureResult> run = findFixtureScriptFor(RecreateSimpleObjects.class).run(null);
-        return run.get(0).getObject();
-    }
+<mb3:section>
+    <mb3:named>Fixtures</mb3:named>
+    <mb3:serviceAction
+        objectType="isis.testing.fixtures.FixtureScripts"
+        id="runFixtureScript"/>
+    <mb3:serviceAction
+        objectType="isis.testing.fixtures.FixtureScripts"
+        id="recreateObjectsAndReturnFirst"/>
+</mb3:section>
 ----
 
 Let's now look at the `FixtureScript` class, where there's a bit more going on.
@@ -139,19 +150,19 @@ public class RecreateSimpleObjects extends FixtureScript {       // <.>
     }
 }
 ----
-<1> inherit from `org.apache.isis.applib.fixturescripts.FixtureScript`
-<2> a hard-coded list of values for the names.
+<.> inherit from xref:refguide:testing:index/fixtures/applib/fixturescripts/FixtureScript.adoc[FixtureScript]
+<.> a hard-coded list of values for the names.
 Note that the xref:testing:fakedata:about.adoc[Fakedata] testing module could also have been used
-<3> whether the script is "discoverable"; in other words whether it should be rendered in the drop-down by the `FixtureScripts` service
-<4> input property: the number of objects to create, up to 10; for the calling test to specify, but note this is optional and has a default (see below).
+<.> whether the script is "discoverable"; in other words whether it should be rendered in the drop-down by the xref:refguide:testing:index/fixtures/applib/fixturescripts/FixtureScripts.adoc[FixtureScripts] domain service
+<.> input property: the number of objects to create, up to 10; for the calling test to specify, but note this is optional and has a default (see below).
 It's important that a wrapper class is used (ie `java.lang.Integer`, not `int`)
-<5> output property: the generated list of objects, for the calling test to grab
-<6> the mandatory execute(...) API
-<7> the `defaultParam(...)` (inherited from `FixtureScript`) will default the `number` property (using Java's Reflection API) if none was specified
-<8> call another fixture script (`SimpleObjectsTearDown`) using the provided `ExecutionContext`.
-Note that although the fixture script is a view model, it's fine to simply instantiate it (rather than using `FactoryService#create(...)`).
-<9> calling another fixture script (`SimpleObjectCreate`) using the provided `ExecutionContext`
-<10> adding the created object to the list, for the calling object to use.
+<.> output property: the generated list of objects, for the calling test to grab
+<.> the mandatory execute(...) API
+<.> the `defaultParam(...)` (inherited from `FixtureScript`) will default the `number` property (using Java's Reflection API) if none was specified
+<.> call another fixture script (`SimpleObjectsTearDown`) using the provided `ExecutionContext`.
+There's no need to instantiate using the xref:refguide:applib:index/services/factory/FactoryService.adoc[FactoryService].
+<.> calling another fixture script (`SimpleObjectCreate`) using the provided `ExecutionContext`
+<.> adding the created object to the list, for the calling object to use.
 
 Because this script has exposed a "number" property, it's possible to set this from within the UI.
 For example:
@@ -161,48 +172,6 @@ image::prompt-specifying-number.png[width="700px"]
 When this is executed, the framework will parse the text and attempt to reflectively set the corresponding properties on the fixture result.
 So, in this case, when the fixture script is executed we actually get 6 objects created.
 
-== Using within Tests
-
-Fixture scripts can be called from integration tests just the same way that fixture scripts can call one another.
-
-For example, here's an integration test from the xref:docs:starters:simpleapp.adoc[SimpleApp] starter app:
-
-// TODO: v2: this will be out of date, no doubt.
-
-[source,java]
-----
-public class SimpleObjectIntegTest extends SimpleAppIntegTest {
-    SimpleObject simpleObjectWrapped;
-    @Before
-    public void setUp() throws Exception {
-        // given
-        RecreateSimpleObjects fs =
-             new RecreateSimpleObjects().setNumber(1);  // <1>
-        fixtureScripts.runFixtureScript(fs, null);      // <2>
-
-        SimpleObject simpleObjectPojo =
-            fs.getSimpleObjects().get(0);               // <3>
-        assertThat(simpleObjectPojo).isNotNull();
-
-        simpleObjectWrapped = wrap(simpleObjectPojo);   // <4>
-    }
-    @Test
-    public void accessible() throws Exception {
-        // when
-        final String name = simpleObjectWrapped.getName();
-        // then
-        assertThat(name).isEqualTo(fs.NAMES.get(0));
-    }
-    ...
-    @Inject
-    FixtureScripts fixtureScripts;                      // <5>
-}
-----
-<1> instantiate the fixture script for this test, and configure
-<2> execute the fixture script
-<3> obtain the object under test from the fixture
-<4> wrap the object (to simulate being interacted with through the UI)
-<5> inject the `FixtureScripts` domain service (just like any other domain service)
 
 == Personas and Builders
 
@@ -213,7 +182,9 @@ At the same time, "Persona" instances of entity classes help the developer becom
 For example, "Steve Single" the Customer might be 21, single and no kids, whereas vs "Meghan Married-Mum" the Customer might be married 35 with 2 kids.
 Using "Steve" vs "Meghan" immediately informs the developer about the particular scenario being explored.
 
-The `PersonaWithBuilderScript` and `PersonaWithFinder` interfaces are intended to be implemented typically by "persona" enums, where each enum instance captures the essential data of some persona.
+The xref:refguide:testing:index/fixtures/applib/fixturescripts/
+
+`PersonaWithBuilderScript` and `PersonaWithFinder` interfaces are intended to be implemented typically by "persona" enums, where each enum instance captures the essential data of some persona.
 So, going back to the previous example, we might have:
 
 [source,xml]
@@ -316,31 +287,44 @@ public class SimpleObjectBuilder
 <3> the created entity is provided as an output
 
 
-This simplifies the integration tests considerably:
+== Using within Tests
+
+Fixture scripts can be called from integration tests just the same way that fixture scripts can call one another.
+
+For example, here's part of an integration test from the xref:docs:starters:simpleapp.adoc[SimpleApp] starter app:
 
 [source,java]
+.SimpleObject_IntegTest.java
 ----
+@Transactional
 public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
 
     SimpleObject simpleObject;
 
-    @Before
+    @BeforeEach
     public void setUp() {
         // given
-        simpleObject = fixtureScripts.runBuilderScript(SimpleObject_persona.FOO.builder());
+        simpleObject = fixtureScripts.runPersona(SimpleObject_persona.FOO); // <.>
     }
 
-    @Test
-    public void accessible() {
-        // when
-        final String name = wrap(simpleObject).getName();
+    public static class updateName extends SimpleObject_IntegTest {
+
+        @Test
+        public void can_be_updated_directly() {
 
-        // then
-        assertThat(name).isEqualTo(simpleObject.getName());
+            // when
+            wrap(simpleObject).updateName("new name");
+            transactionService.flushTransaction();
+
+            // then
+            assertThat(wrap(simpleObject).getName()).isEqualTo("new name");
+        }
+
+        // ...
     }
-    ...
 }
 ----
+<.> runs a persona fixture script and stores the resultant domain object for testing.
 
 Put together, the persona enums provide the "what" - hard-coded values for certain key data that the developer becomes very familiar with - while the builder provides the "how-to".
 
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/FixtureScriptWithExecutionStrategy.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/FixtureScriptWithExecutionStrategy.java
index 61fa0e6..ca80e3c 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/FixtureScriptWithExecutionStrategy.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/FixtureScriptWithExecutionStrategy.java
@@ -23,9 +23,16 @@ import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
 import org.apache.isis.testing.fixtures.applib.fixturespec.FixtureScriptsSpecification;
 
 /**
- * Overrides the {@link FixtureScriptsSpecification#getMultipleExecutionStrategy() globally-defined}
+ * Interface for {@link org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript}s to optionally implement,
+ * used to override the {@link FixtureScriptsSpecification#getMultipleExecutionStrategy() globally-defined}
  * {@link org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts.MultipleExecutionStrategy}
- * strategy, allowing individual fixtures to indicate that they have their own execution strategy.
+ * strategy.
+ *
+ * <p>
+ *     This therefore allows individual fixture scripts to indicate that they have their own execution strategy.
+ * </p>
+ *
+ * @since 2.x {@index}
  */
 public interface FixtureScriptWithExecutionStrategy {
 
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithBuilderScript.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithBuilderScript.java
index 1cf7f55..1a87795 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithBuilderScript.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithBuilderScript.java
@@ -20,8 +20,23 @@ package org.apache.isis.testing.fixtures.applib.api;
 
 import org.apache.isis.testing.fixtures.applib.fixturescripts.BuilderScriptAbstract;
 
+/**
+ * Intended for persona enums to implement, to provide an instance of a {@link BuilderScriptAbstract} in order to
+ * instantiate an instance of the persona (normally in the form of a domain entity or set of related domain entities).
+ *
+ * <p>
+ *     ({@link BuilderScriptAbstract} is a specialization of
+ *     {@link org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript}).
+ * </p>
+ *
+ * @see PersonaWithFinder
+ * @since 2.x {@index}
+ */
 public interface PersonaWithBuilderScript<T extends BuilderScriptAbstract<?>>  {
 
+    /**
+     * Returns a {@link BuilderScriptAbstract} to use to instantiate this persona.
+     */
     T builder();
 
 }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithFinder.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithFinder.java
index e29b1a2..1c585e2 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithFinder.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/PersonaWithFinder.java
@@ -19,9 +19,31 @@
 package org.apache.isis.testing.fixtures.applib.api;
 
 import org.apache.isis.applib.services.registry.ServiceRegistry;
+import org.apache.isis.testing.fixtures.applib.fixturescripts.BuilderScriptAbstract;
 
+/**
+ * Intended for persona enums to implement, to obtain an instance of the corresponding top-level entity representing
+ * the persona.
+ *
+ * @see PersonaWithBuilderScript
+ *
+ * @since 2.x {@index}
+ */
 public interface PersonaWithFinder<T> {
 
+    /**
+     * Looks up the top-level domain entity representing the persona, with the provided {@link ServiceRegistry}
+     * parameter providing access to all domain services available.
+     *
+     * <p>
+     *     Typically the implementation looks up the appropriate domain-specific repository domain service (or could
+     *     just use the generic {@link org.apache.isis.applib.services.repository.RepositoryService} in order to
+     *     find by key.
+     * </p>
+     *
+     * @param serviceRegistry
+     * @return
+     */
     T findUsing(final ServiceRegistry serviceRegistry);
 
 }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/WithPrereqs.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/WithPrereqs.java
index b11455a..44539d1 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/WithPrereqs.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/WithPrereqs.java
@@ -21,9 +21,20 @@ package org.apache.isis.testing.fixtures.applib.api;
 import org.apache.isis.testing.fixtures.applib.fixturescripts.BuilderScriptAbstract;
 import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript;
 
+/**
+ * Provides a mechanism for {@link FixtureScript}s to specify prerequisites
+ * to be executed first.
+ *
+ * <p>
+ *     Most commonly used to chain {@link BuilderScriptAbstract}s in conjunction
+ *     with personas.
+ * </p>
+ *
+ * @since 2.x {@index}
+ */
 public interface WithPrereqs<T> {
 
-    BuilderScriptAbstract<T> setPrereq(Block<T> prereq);
+    BuilderScriptAbstract<T> addPrereq(Block<T> prereq);
 
     void execPrereqs(FixtureScript.ExecutionContext executionContext);
 
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/package-info.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/package-info.java
deleted file mode 100644
index 0daaa12..0000000
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/api/package-info.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  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.
- */
-
-/**
- * Provides a mechanism to set up an application, typically running in prototype mode (with an in-memory database)
- * or for integration testing.
- *
- *
- */
-package org.apache.isis.testing.fixtures.applib.api;
\ No newline at end of file
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/Clock.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/Clock.java
index 24796d3..0770400 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/Clock.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/Clock.java
@@ -45,6 +45,8 @@ import lombok.val;
  * uses the system's own clock. Alternate implementations can be created via
  * suitable subclasses, but this must be done <b><i>before</i></b> the first
  * call to {@link #getInstance()}.
+ *
+ * @since 2.x {@index}
  */
 public abstract class Clock {
 
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/FixtureClock.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/FixtureClock.java
index 2c97ca5..a944dc3 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/FixtureClock.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/FixtureClock.java
@@ -34,6 +34,8 @@ import java.util.TimeZone;
  * (eg automatic ticking of the clock). That is, the time returned is always
  * explicitly under the control of the programmer (it can be moved forward or
  * back as required).
+ *
+ * @since 2.x {@index}
  */
 public class FixtureClock extends Clock {
     private static final TimeZone UTC_TIME_ZONE;
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/TickingFixtureClock.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/TickingFixtureClock.java
index b8994f2..26a47c5 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/TickingFixtureClock.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/TickingFixtureClock.java
@@ -23,6 +23,9 @@ import java.time.Instant;
 import java.util.Calendar;
 import java.util.TimeZone;
 
+/**
+ * @since 2.x {@index}
+ */
 public class TickingFixtureClock extends Clock {
     private static final TimeZone UTC_TIME_ZONE;
 
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/fixture/TickingClockFixture.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/fixture/TickingClockFixture.java
index e585e65..889ffe0 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/fixture/TickingClockFixture.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/clock/fixture/TickingClockFixture.java
@@ -31,6 +31,9 @@ import org.apache.isis.testing.fixtures.applib.clock.Clock;
 import org.apache.isis.testing.fixtures.applib.clock.FixtureClock;
 import org.apache.isis.testing.fixtures.applib.clock.TickingFixtureClock;
 
+/**
+ * @since 2.x {@index}
+ */
 @Programmatic
 public class TickingClockFixture
 extends FixtureScript
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstalledEvent.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstalledEvent.java
index 56c05f3..2d65b44 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstalledEvent.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstalledEvent.java
@@ -21,6 +21,9 @@ package org.apache.isis.testing.fixtures.applib.events;
 
 import org.apache.isis.applib.events.EventObjectBase;
 
+/**
+ * @since 2.x {@index}
+ */
 public class FixturesInstalledEvent extends EventObjectBase<Object> {
 
     public FixturesInstalledEvent(final Object source) {
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstallingEvent.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstallingEvent.java
index 463f373..fbe76eb 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstallingEvent.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/events/FixturesInstallingEvent.java
@@ -21,6 +21,9 @@ package org.apache.isis.testing.fixtures.applib.events;
 
 import org.apache.isis.applib.events.EventObjectBase;
 
+/**
+ * @since 2.x {@index}
+ */
 public class FixturesInstallingEvent extends EventObjectBase<Object> {
 
     public FixturesInstallingEvent(final Object source) {
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptAbstract.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptAbstract.java
index 19519d3..1b475ee 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptAbstract.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptAbstract.java
@@ -30,6 +30,13 @@ import org.apache.isis.testing.fixtures.applib.api.WithPrereqs;
 import lombok.Getter;
 
 /**
+ * A specialization of {@link FixtureScript} that is intended to be used to
+ * setup the state of a {@link PersonaWithBuilderScript persona}.
+ *
+ * <p>
+ *     The {@link PersonaWithBuilderScript persona} represents the &quot;what&quot;, in other words the raw data,
+ *     while the {@link BuilderScriptAbstract build script} represents the &quot;how-to&quot;.
+ * </p>
  * @since 2.x {@index}
  */
 public abstract class BuilderScriptAbstract<T>
@@ -98,7 +105,7 @@ extends FixtureScript implements WithPrereqs<T>, FixtureScriptWithExecutionStrat
     private final List<WithPrereqs.Block<T>> prereqs = _Lists.newArrayList();
 
     @Override
-    public BuilderScriptAbstract<T> setPrereq(WithPrereqs.Block<T> prereq) {
+    public BuilderScriptAbstract<T> addPrereq(WithPrereqs.Block<T> prereq) {
         prereqs.add(prereq);
         return this;
     }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithResult.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithResult.java
index 67c3733..8569f05 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithResult.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithResult.java
@@ -23,21 +23,39 @@ import org.apache.isis.applib.annotation.Programmatic;
 import lombok.Getter;
 
 /**
+ * A specialization of {@link BuilderScriptAbstract} which expects there to be
+ * a top-level object, and so - by defining its own {@link #buildResult(ExecutionContext) hook method} - removes a little of the boilerplate..
+ *
  * @since 2.x {@index}
  *
  * @param <T>
  */
 public abstract class BuilderScriptWithResult<T> extends BuilderScriptAbstract<T> {
 
-    @Getter(onMethod=@__({@Override}))
     public T object;
 
-    @Programmatic
-    protected abstract T buildResult(final ExecutionContext ec);
+    /**
+     * Simply returns the object returned by {@link #buildResult(ExecutionContext)}.
+     * @return
+     */
+    @Override
+    public final T getObject() {
+        return object;
+    }
 
+    /**
+     * Concrete implementation that simply executes {@link #buildResult(ExecutionContext)} and stores the
+     * result to be accessed by {@link #getObject()}.
+     */
     @Override
     protected final void execute(final ExecutionContext executionContext) {
         object = buildResult(executionContext);
     }
 
+    /**
+     * Hook method to return a single object.
+     */
+    @Programmatic
+    protected abstract T buildResult(final ExecutionContext ec);
+
 }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithoutResult.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithoutResult.java
index 3d42804..22ce0e0 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithoutResult.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/BuilderScriptWithoutResult.java
@@ -19,12 +19,18 @@
 package org.apache.isis.testing.fixtures.applib.fixturescripts;
 
 /**
+ * A specialization of {@link BuilderScriptAbstract} which returns no
+ * top-level object, and so removes a little of the boilerplate that would otherwise be required.
+ *
  * @since 2.x {@index}
  */
 public abstract class BuilderScriptWithoutResult extends BuilderScriptAbstract<Object> {
 
+    /**
+     * Simply returns null.
+     */
     @Override
-    public Object getObject() {
+    public final Object getObject() {
         return null;
     }
 
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault.java
index 449ee80..b035227 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/ExecutionParametersDefault.java
@@ -42,7 +42,7 @@ import org.apache.isis.commons.internal.collections._Maps;
  *     The class is instantiated by the {@link ExecutionParametersService}.
  * </p>
  *
- * @since 1.x {@index}
+ * @since 2.0 {@index}
  */
 public class ExecutionParametersDefault implements ExecutionParameters {
 
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturespec/package-info.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturespec/package-info.java
deleted file mode 100644
index 4f3f9d8..0000000
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturespec/package-info.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  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.
- */
-
-/**
- * The {@link org.apache.isis.testing.fixtures.applib.fixturespec.FixtureScriptsSpecificationProvider} SPI service configures the {@link org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts} domain service.
- *
- *
- */
-package org.apache.isis.testing.fixtures.applib.fixturespec;
\ No newline at end of file
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/services/FixturesLifecycleService.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/services/FixturesLifecycleService.java
index 80fa041..19e7c1b 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/services/FixturesLifecycleService.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/services/FixturesLifecycleService.java
@@ -42,6 +42,9 @@ import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
 
 import lombok.extern.log4j.Log4j2;
 
+/**
+ * @since 2.0 {@index}
+ */
 @Service
 @Named("isis.test.FixturesLifecycleService")
 @Order(OrderPrecedence.MIDPOINT)