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 2017/12/20 13:19:22 UTC

[isis] branch master updated (fabbe0b -> e5bdbd4)

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

danhaywood pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from fabbe0b  ISIS-1465: tiny doc fix
     new 8dc422c  ISIS-1791: tidies up ClockFixture, TickingClockFixture, updates docs.
     new e5bdbd4  ISIS-1791 and ISIS-1794: refactorings of ClockFixture and TickingClockFixture.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ..._ugfun_getting-started_simpleapp-archetype.adoc | 193 ++++++------
 .../guides/ugtst/_ugtst_bdd-spec-support.adoc      |   1 -
 .../guides/ugtst/_ugtst_fixture-scripts.adoc       |  18 +-
 .../_ugtst_fixture-scripts_api-and-usage.adoc      | 327 ++++++++++-----------
 .../ugtst/_ugtst_fixture-scripts_sudo-service.adoc |   6 +-
 ...tst_fixture-scripts_ticking-clock-fixture.adoc} |  22 +-
 .../images/testing/fixture-scripts/prompt.png      | Bin 52869 -> 49181 bytes
 .../testing/fixture-scripts/prototyping-menu.png   | Bin 59183 -> 58104 bytes
 .../result-list-specifying-number.png              | Bin 63100 -> 0 bytes
 .../images/testing/fixture-scripts/result-list.png | Bin 50272 -> 82117 bytes
 .../apache/isis/applib/AppManifestAbstract.java    |  10 +-
 .../java/org/apache/isis/applib/clock/Clock.java   |   2 +-
 .../{clock => fixtures}/TickingFixtureClock.java   |   6 +-
 .../applib/fixturescripts/clock/ClockFixture.java  |  91 +++---
 .../fixturescripts/clock/TickingClockFixture.java  | 103 ++++++-
 .../core/runtime/headless/HeadlessAbstract.java    |   2 +-
 .../runtime/headless/IsisSystemBootstrapper.java   |   2 +-
 .../application/manifest/DomainAppAppManifest.java |  12 +-
 .../manifest/DomainAppAppManifestWithFixtures.java |   7 +-
 .../services/homepage/HomePageViewModel.java       |   6 +-
 .../services/homepage/HomePageViewModel.layout.xml |   1 +
 .../application/integtests/Smoke_IntegTest.java    |  25 +-
 .../domainapp/modules/simple/SimpleModule.java     |   7 -
 .../simple/dom/impl/SimpleObjectRepository.java    |  69 -----
 .../{SimpleObjectMenu.java => SimpleObjects.java}  |  37 ++-
 .../simple/fixture/SimpleObjectBuilder.java        |   6 +-
 .../simple/fixture/SimpleObject_persona.java       |  14 +-
 ...epository_Test.java => SimpleObjects_Test.java} |  22 +-
 .../tests/SimpleObjectMenu_IntegTest.java          |  64 +---
 .../integtests/tests/SimpleObject_IntegTest.java   |  32 +-
 .../simple/specglue/SimpleObjectMenuGlue.java      |   8 +-
 31 files changed, 550 insertions(+), 543 deletions(-)
 copy adocs/documentation/src/main/asciidoc/guides/{rgant/_rgant-DomainObjectLayout_plural.adoc => ugtst/_ugtst_fixture-scripts_ticking-clock-fixture.adoc} (50%)
 delete mode 100644 adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list-specifying-number.png
 rename core/applib/src/main/java/org/apache/isis/applib/{clock => fixtures}/TickingFixtureClock.java (98%)
 delete mode 100644 example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjectRepository.java
 rename example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/{SimpleObjectMenu.java => SimpleObjects.java} (65%)
 rename example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/{SimpleObjectRepository_Test.java => SimpleObjects_Test.java} (82%)

-- 
To stop receiving notification emails like this one, please contact
['"commits@isis.apache.org" <co...@isis.apache.org>'].

[isis] 02/02: ISIS-1791 and ISIS-1794: refactorings of ClockFixture and TickingClockFixture.

Posted by da...@apache.org.
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/isis.git

commit e5bdbd4eec920d65f3645890390792f42cbc1a82
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Dec 20 13:19:09 2017 +0000

    ISIS-1791 and ISIS-1794: refactorings of ClockFixture and TickingClockFixture.
    
    Also documentation of this and persona builder scripts
---
 ..._ugfun_getting-started_simpleapp-archetype.adoc | 195 ++++++++++++---------
 .../guides/ugtst/_ugtst_fixture-scripts.adoc       |   2 +-
 .../_ugtst_fixture-scripts_api-and-usage.adoc      |  31 ++--
 ...tst_fixture-scripts_ticking-clock-fixture.adoc} |  20 +--
 .../java/org/apache/isis/applib/clock/Clock.java   |   2 +-
 .../{clock => fixtures}/TickingFixtureClock.java   |   6 +-
 .../applib/fixturescripts/clock/ClockFixture.java  |   1 -
 .../fixturescripts/clock/TickingClockFixture.java  |  81 ++++++++-
 .../core/runtime/headless/HeadlessAbstract.java    |   2 +-
 .../runtime/headless/IsisSystemBootstrapper.java   |   2 +-
 .../services/homepage/HomePageViewModel.java       |   6 +-
 .../application/integtests/Smoke_IntegTest.java    |  25 +--
 .../simple/dom/impl/SimpleObjectRepository.java    |  69 --------
 .../{SimpleObjectMenu.java => SimpleObjects.java}  |  37 +++-
 .../simple/fixture/SimpleObjectBuilder.java        |   6 +-
 .../simple/fixture/SimpleObject_persona.java       |   6 +-
 ...epository_Test.java => SimpleObjects_Test.java} |  22 +--
 .../tests/SimpleObjectMenu_IntegTest.java          |   4 +-
 .../simple/specglue/SimpleObjectMenuGlue.java      |   8 +-
 19 files changed, 276 insertions(+), 249 deletions(-)

diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc
index 47a1627..d797771 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc
@@ -5,6 +5,9 @@
 :_imagesdir: images/
 
 
+NOTE: this document has been updated for `1.16.0-SNAPSHOT`.
+
+
 The quickest way to get started building an application "for real" is to run the `simpleapp` archetype.
 Like the xref:ugfun.adoc#_ugfun_getting-started_helloworld-archetype[helloworld archetype], this too will generate a very simple one-class domain model (an entity called `SimpleObject` with a couple of properties).
 
@@ -96,19 +99,29 @@ Of course, you are always free to move the classes to a different package if you
 
 === myapp-application
 
-The `myapp-application` module has three main packages, the most important being `domainapp.application.manifest`.
-
-Classes for this package can be found under `src/main/java`:
+The production classes for `myapp-application` module (in `src/main/java`) are:
 
 [monotree]
 ----
 > domainapp/
 >> application/
+>>> DomainAppApplicationModule.java
+>>> fixture/
+>>>> DomainAppFixtureScriptsSpecificationProvider.java
+>>>> scenarios/
+>>>>> DomainAppDemo.java
 >>> manifest/
 >>>> DomainAppAppManifest.java
 >>>> DomainAppAppManifestBypassSecurity.java
 >>>> DomainAppAppManifestWithFixtures.java
 >>>> DomainAppAppManifestWithFixturesBypassSecurity.java
+>>>> menubars.layout.xml
+>>> services
+>>>> homepage
+>>>>> HomePageService.java
+>>>>> HomePageViewModel.java
+>>>>> HomePageViewModel.layout.xml
+>>>>> HomePageViewModel.layout.png
 ----
 
 There are also supporting files in this package in `src/main/resources`:
@@ -130,20 +143,17 @@ It is quite short:
 
 [source,java]
 ----
-public class DomainAppAppManifest extends AppManifestAbstract {
+public class DomainAppAppManifest extends AppManifestAbstract2 {
 
-    public static final Builder BUILDER = Builder.forModules(
-                    SimpleModuleDomSubmodule.class,
-                    DomainAppApplicationModuleFixtureSubmodule.class,
-                    DomainAppApplicationModuleServicesSubmodule.class
-            )
+    public static final Builder BUILDER = Builder
+            .forModule(new DomainAppApplicationModule())
             .withConfigurationPropertiesFile(DomainAppAppManifest.class,
                     "isis.properties",
                     "authentication_shiro.properties",
                     "persistor_datanucleus.properties",
                     "viewer_restfulobjects.properties",
-                    "viewer_wicket.properties"
-            ).withAuthMechanism("shiro");
+                    "viewer_wicket.properties")
+            .withAuthMechanism("shiro");
 
     public DomainAppAppManifest() {
         super(BUILDER);
@@ -151,32 +161,33 @@ public class DomainAppAppManifest extends AppManifestAbstract {
 }
 ----
 
-The manifest uses the builder defined by `AppManifestAbstract` and references 3 (Isis) modules.
-These are simply classes that identify packages to search for entities, domain services and fixtures; one defined in the `myapp-module-simple` module, and two package within the `myapp-application` module itself (for additional fixtures and services, namely the home page which we'll discuss below).
+The manifest uses the builder defined by `AppManifestAbstract2` and references a single top-level (Isis) module, namely `DomainAppApplicationModule`:
 
-The manifest also defines a number of static configuration files, all loaded from the classpath.
-Each file contains configuration setting for a different part of the runtime (`isis.properties` for the core framework, shiro for security, datanucleus for the objectstore, and the two viewers).
+[source,java]
+----
+public class DomainAppApplicationModule extends ModuleAbstract {
+    @Override
+    public Set<Module> getDependencies() {
+        return Sets.<Module>newHashSet(new SimpleModule());
+    }
+}
+----
 
-There are also several variations on the app manifest; these can be used to bootstrap the application with fixtures, or disabling security.
+where `SimpleModule` in defined in the `mypp-module-simple` module (below).
 
+The primary purpose of the module class is to identify packages and subpackages that the framework should scan for entities and domain services.
+The transitive dependencies between modules are automatically resolved.
+The net effect is that all the domain services and entities in this module as well as those modules referenced are included into the app.
 
-The next package is `domainapp.application.services`:
+Going back to the manifest, it also defines a number of static configuration files, all loaded from the classpath.
+Each file contains configuration setting for a different part of the runtime (`isis.properties` for the core framework, shiro for security, datanucleus for the objectstore, and the two viewers).
 
-[monotree]
-----
-> domainapp/
->> application/
->>> services/
->>>> DomainAppApplicationModuleServicesSubmodule.java
->>>> homepage/
->>>>> HomePageService.java
->>>>> HomePageViewModel.java
->>>>> HomePageViewModel.layout.xml
->>>>> HomePageViewModel.png
-----
+The `menubars.layout.xml` file also resides in the same package as the manifest; this defines the menubar structure.
+
+There are also several variations on the app manifest; these can be used to bootstrap the application with fixtures, or disabling security.
 
-The `DomainAppApplicationModuleServicesSubmodule` class is referenced as a module within the app manifest, meaning that the `HomePageService` that sits in a subpackage underneath it is picked up automatically.
-This domain service simply has a single action annotated with `@HomePage`:
+The `domainapp.application.services` package contains the `HomePageService` domain service.
+This simply has a single action annotated with `@HomePage`:
 
 [source,java]
 ----
@@ -190,26 +201,10 @@ public HomePageViewModel homePage() {
 which returns the `HomePageViewModel` for use as the home page.
 The `HomePageViewModel` itself just renders a collection of ``SimpleObject``s in a list (`HomePageViewModel.layout.xml` defines the UI layout).
 
-The final package in the application module is `domainapp.application.fixture`:
-
-[monotree]
-----
-> domainapp/
->> application/
->>> fixture/
->>>> DomainAppApplicationModuleFixtureSubmodule.java
->>>> DomainAppFixtureScriptsSpecificationProvider.java
->>>> scenarios/
->>>>> DomainAppDemo.java
->>>> teardown/
->>>>> DomainAppTearDown.java
-----
-
-The important class here is `DomainAppDemo`, which is a fixture script that can be used to setup the application with some dummy data.
+The final package in the application module is `domainapp.application.fixture`.
+The important class here is `DomainAppDemo`, a fixture script that can be used to setup the application with some dummy data.
 This is used in the app itself when running in prototype mode (against an in-memory database), and can also be used by integration tests.
 
-The `DomainAppApplicationModuleFixtureSubmodule` is referenced by the app manifest, meaning that the framework knows to search for domain services and fixtures under its package.
-
 There is in fact also a domain service defined here, namely `DomainAppFixtureScriptsSpecificationProvider`.
 This is just used to configure the run fixture script menu item shown on the "Prototyping" menu.
 
@@ -229,6 +224,8 @@ The BDD specs (run using Cucumber) reside under `domain.application.bdd`:
 >>>>> SimpleObjectSpec_listAllAndCreate.feature
 ----
 
+Here the `BootstrappingGlue` glue class inherits from the framework's `CukeGlueBootstrappingAbstract` class, and bootstraps using the `DomainAppApplicationModule` mentioned above.
+
 There is just one feature file: `SimpleObjectSpec_listAllAndCreate.feature`, which is pretty simple:
 
 [source,feature]
@@ -236,18 +233,17 @@ There is just one feature file: `SimpleObjectSpec_listAllAndCreate.feature`, whi
 @DomainAppDemo
 Feature: List and Create New Simple Objects
 
-  @integration
   Scenario: Existing simple objects can be listed and new ones created
-    Given there are initially 3 simple objects
+    Given there are initially 10 simple objects
     When  I create a new simple object
-    Then  there are 4 simple objects
+    Then  there are 11 simple objects
 ----
 
-The `@DomainAppDemo` annotation causes the `DomainAppDemo` fixture script to be run; this sets up 3 objects.
-The "glue" defines both in the `myapp-application` module and in the `myapp-module-simple` module
 
-The tests themselves are run by the `RunIntegBddSpecs.java` class; this is standard Cucumber bootstrapping.
+The `@DomainAppDemo` annotation causes the `DomainAppDemo` fixture script to be run; this is the purpose of the `CatalogOfFixturesGlue` glue class.
 
+The specs themselves are run by the `RunIntegBddSpecs.java` class, which specifies which packages to search for "glue".
+This is just standard Cucumber bootstrapping.
 
 The integration tests meanwhile are in `domainapp.application.integtests`:
 
@@ -260,18 +256,16 @@ The integration tests meanwhile are in `domainapp.application.integtests`:
 >>>> Smoke_IntegTest.java
 ----
 
-The `Smoke_IntegTest` inherits `DomainAppIntegTestAbstract`, with the latter bootstrapping the framework using the `DomainAppAppManifest` already discussed that is used for running the application itself.
+The `Smoke_IntegTest` inherits `DomainAppIntegTestAbstract`, which in turn inherits from `IntegrationTestAbstract3` and uses the `DomainAppApplicationModule` previously discussed.
 Moreover, the `Smoke_IntegTest` uses the same `DomainAppDemo` fixture script.
 The application and the smoke tests therefore run with the exact same state, making debugging easy.
 
-The BDD specs and integration tests are named according to the naming convention required by the "surefire" mavenmixin that configures the maven surefire plugin.
+With regard to the naming of these various BDD specs and integration tests, they follow the naming convention required by the (non-ASF) link:http://github.com/danhaywood/java-mavenmixin-surefire["surefire" mavenmixin] that configures the maven surefire plugin.
 
 
 
 === myapp-module-simple
 
-NOTE: this is out of date for 1.16.0-SNAPSHOT
-
 This module is where the domain object model lives, that is the business logic of the application itself.
 This typically comprises entities, domain services, mixins and view models.
 
@@ -292,9 +286,9 @@ Under `src/main/java` we have:
 > domainapp/
 >> modules/
 >>> simple/
+>>>> SimpleModule.java
 >>>> SimpleModuleManifest.java
 >>>> dom/
->>>>> SimpleModuleDomSubmodule.java
 >>>>> impl/
 >>>>>> SimpleObject.java
 >>>>>> SimpleObject.layout.xml
@@ -302,35 +296,39 @@ Under `src/main/java` we have:
 >>>>>> SimpleObjectMenu.java
 >>>>>> SimpleObjectRepository.java
 >>>> fixture/
->>>>> SimpleModuleFixtureSubmodule.java
->>>>> scenario/
->>>>>> CreateSimpleObjects.java
->>>>>> SimpleObjectData.java
->>>>> teardown/
->>>>>> SimpleModuleTearDown.java
+>>>>> SimpleObject_persona.java
+>>>>> SimpleObjectBuilder.java
 > META-INF/
 >> persistence.xml
 ----
 
-Note once more that the module class (`SimpleModuleDomSubmodule`) is referenced in the app manifest class, meaning that all the entities, domain services and fixtures within it are included within the application.
-Speaking of which...
-
-`SimpleObject` is the (one-and-only) domain entity defined (with `SimpleObject.layout.xml` defines its layout in the UI).
-In contrast to the helloworld app, though, there are _two_ associated domain services:
+The `SimpleModule` is the (single) module class referenced from the previously discussed `DomainAppApplicationModule`, meaning that all the entities, domain services and fixtures within it are included within the application.
 
-* `SimpleObjectMenu` domain service's actions appear as menu items, to create and find ``SimpleObject``s.
-This delegates in turn to:
+* `SimpleObject` is the (one-and-only) domain entity defined (with `SimpleObject.layout.xml` defines its layout in the UI).
 
-* `SimpleObjectRepository`, which is a repository domain service that actually does the fetching and creating in the database.
+* `SimpleObjects` domain service's whos actions appear as menu items and which acts as a repository to create and find ``SimpleObject``s.
 
-Splitting out domain services like this is quite common since it allows more flexibility with the menu structure.
+The `SimpleModule` class also defines a teardown fixture, automatically called by integration tests.
 
-The module also defines its own manifest, `SimpleModuleManifest`.
-This is used to run Isis' own xref:../rgmvn/rgmvn.adoc#[maven plugin] to xref:../rgmvn/rgmvn.adoc#_rgmvn_validate[validate] the domain object model (eg to detect orphaned supported methods).
-
-Under `fixture.scenario` subpackage are fixture scripts that are used by integration tests and by the demo fixture script defined in the `myapp-application` module (discussed above).
+[source,java]
+----
+public class SimpleModule extends ModuleAbstract {
+    @Override
+    public FixtureScript getTeardownFixture() {
+        return new TeardownFixtureAbstract2() {
+            @Override
+            protected void execute(ExecutionContext ec) {
+                deleteFrom(SimpleObject.class);
+            }
+        };
+    }
+    ...
+}
+----
 
+In the `fixture` subpackage is the `SimpleObject_persona` "persona" which uses the corresponding `SimpleObjectBuilder` builder script; further discussion on this pattern xref:../ugtst/ugtst.adoc#_ugtst_fixture-scripts_api-and-usage_persona-and-builders[here].
 These fixtures are also used by "local" integration tests, which reside under `src/test/java`.
+
 There are also unit tests and "glue" for the BDD specs:
 
 [monotree]
@@ -354,8 +352,12 @@ There are also unit tests and "glue" for the BDD specs:
 The simpleapp application has both "local" integration tests (defined within the `myapp-module-simple` module) and also "global" integration tests (the "smoke" tests in `myapp-application` module).
 There's a role for both: local integration tests should fully exercise the module but may need to mock out collaborations between modules, while global integration tests exercise the whole application (but an over-reliance on these can cause test run times to bloat).
 
-The surefire mavenmixin plugin configured in the `pom.xml` establishes the convention that integration tests include the name "IntegTest", while unit tests contain merely "Test".
-The `SimpleModuleIntegTestAbstract` also uses the `SimpleAppManifest` (mentioned above) to define a "cut-down" version of the application that just bootstraps the simple module.
+With regard to the naming of these various BDD specs and integration tests, they follow the naming convention required by the (non-ASF) link:http://github.com/danhaywood/java-mavenmixin-surefire["surefire" mavenmixin] that configures the maven surefire plugin.
+Integration tests include the name "IntegTest", while unit tests contain merely "Test".
+
+The module also defines its own manifest, `SimpleModuleManifest`.
+This is used to run Isis' own xref:../rgmvn/rgmvn.adoc#[maven plugin] to xref:../rgmvn/rgmvn.adoc#_rgmvn_validate[validate] the domain object model (eg to detect orphaned supported methods).
+
 
 
 === myapp-webapp
@@ -372,7 +374,8 @@ Under `src/main/java` there is:
 >>> welcome.html
 ----
 
-The `DomainApplication` is required to bootstrap the Wicket viewer (it is configured in `WEB-INF/web.xml`).
+The `DomainApplication` is required to bootstrap the Wicket viewer (it is configured in `WEB-INF/web.xml`, discussed below).
+Within `DomainApplication` is the bootstrapping of the Wicket viewer.
 Internally it uses Google Guice to configure various static resources served up by Wicket:
 
 [source,java]
@@ -395,7 +398,6 @@ public class DomainApplication extends IsisWicketApplication {
 The `configure()` method is the place to change the name of the application for example, or to change the initial about and welcome messages.
 The text of the welcome page shown by the Wicket viewer can be found in `welcome.html`, loaded from the classpath and in the same package as `DomainApplication`.
 
-
 Under `src/main/webapp` we have various resources that are used to configure the webapp, or that are served up by the running webapp:
 
 [monotree]
@@ -415,7 +417,31 @@ Under `src/main/webapp` we have various resources that are used to configure the
 >> web.xml
 ----
 
-Most important of these is `WEB-INF/web.xml`, which bootstraps both the Wicket viewer and the Restful Objects viewer (the REST API derived from the domain object model).
+Most important of these is `WEB-INF/web.xml`, which bootstraps both the Wicket viewer and the Restful Objects viewer (the REST API derived from the domain object model):
+
+[source,xml]
+.web.xml
+----
+<web-app ...>
+  ...
+  <filter>
+    <filter-name>WicketFilter</filter-name>
+    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
+    <init-param>
+      <param-name>applicationClassName</param-name>
+      <param-value>domainapp.webapp.DomainApplication</param-value>
+    </init-param>
+  </filter>
+  ...
+  <context-param>
+    <param-name>javax.ws.rs.Application</param-name>
+    <param-value>
+      org.apache.isis.viewer.restfulobjects.server.RestfulObjectsApplication
+    </param-value>
+  </context-param>
+  ...
+</web-app>
+----
 
 The `about/index.html` is the page shown at the root of the package, providing links to either the Wicket viewer or to the Swagger UI.
 In a production application this is usually replaced with a page that does an HTTP 302 redirect to the Wicket viewer.
@@ -479,7 +505,6 @@ where `myapp` is the `artifactId` entered above.
 
 
 
-
 [[__ugfun_getting-started_simpleapp-archetype_running-the-app]]
 == Running the App
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc
index faa37d0..0875ee8 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc
@@ -47,6 +47,6 @@ The following  sections explain the API and how to go about using the API.
 
 
 include::_ugtst_fixture-scripts_api-and-usage.adoc[leveloffset=+1]
-include::_ugtst_fixture-scripts_clock-fixtures.adoc[leveloffset=+1]
+include::_ugtst_fixture-scripts_ticking-clock-fixture.adoc[leveloffset=+1]
 include::_ugtst_fixture-scripts_sudo-service.adoc[leveloffset=+1]
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc
index 200a9f6..65c8b9d 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc
@@ -14,6 +14,7 @@ You can also subclass from `FixtureScript` to create helpers; more on this below
 
 Let's look at `FixtureScripts` domain service in more detail first.
 
+[[_ugtst_fixture-scripts_api-and-usage_FixtureScripts]]
 == `FixtureScripts`
 
 The framework provides a default implementation of `FixtureScripts` domain service, namely the xref:../rgsvc/rgsvc.adoc#_rgsvc_testing_FixtureScriptsDefault[`FixtureScriptsDefault`] domain service.
@@ -94,6 +95,7 @@ Let's now look at the `FixtureScript` class, where there's a bit more going on.
 
 
 
+[[_ugtst_fixture-scripts_api-and-usage_FixtureScript]]
 == `FixtureScript`
 
 A fixture script is ultimately just a block of code that can be executed, so it's up to you how you implement it to set up the system.
@@ -166,6 +168,7 @@ So, in this case, when the fixture script is executed we actually get 6 objects
 
 
 
+[[_ugtst_fixture-scripts_api-and-usage_using-within-tests]]
 == Using within Tests
 
 Fixture scripts can be called from integration tests just the same way that fixture scripts can call one another.
@@ -180,11 +183,11 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest {
     public void setUp() throws Exception {
         // given
         RecreateSimpleObjects fs =
-             new RecreateSimpleObjects().setNumber(1);  // <2>
-        fixtureScripts.runFixtureScript(fs, null);      // <3>
+             new RecreateSimpleObjects().setNumber(1);  // <1>
+        fixtureScripts.runFixtureScript(fs, null);      // <2>
 
         SimpleObject simpleObjectPojo =
-            fs.getSimpleObjects().get(0);               // <4>
+            fs.getSimpleObjects().get(0);               // <3>
         assertThat(simpleObjectPojo).isNotNull();
 
         simpleObjectWrapped = wrap(simpleObjectPojo);   // <4>
@@ -209,13 +212,13 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest {
 
 
 
-== "Persona" Builder Scripts (`1.16.0-SNAPSHOT`)
+[[_ugtst_fixture-scripts_api-and-usage_persona-and-builders]]
+== Personas and Builders (`1.16.0-SNAPSHOT`)
 
-Good integration tests are probably the best way to understand the behaviour of the domain model: better than reading the code itself.
-Such tests should clearly separating out the "given", from the "when", from the "then".
-The "given" - the initial data set - should be as minimal as possible so that the developer reading the test knows that everything being set up is essential to the functionality under test.
+Good integration tests are probably the best way to understand the behaviour of the domain model: better, even, than reading the code itself.
+This requires though that the tests are as minimal as possible so that the developer reading the test knows that everything mentioned in the test is essential to the functionality under test.
 
-"Persona" instances of entity classes help the developer become familiar with the data being set up.
+At the same time, "Persona" instances of entity classes help the developer become familiar with the data being set up.
 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.
 
@@ -345,14 +348,14 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
 
 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".
 
-Note though that the builder scripts (`BuilderScriptAbstract` implementations) are not only for use by enum personas.
-In a more complex entity there will be many potential values that need to be selected in order to create a valid instance.
-Rather than pushing this responsibility onto the caller, instead the builder script can automatically default some of these values.
+These builder scripts (`BuilderScriptAbstract` implementations) can be used independently of the enum personas.
+And for more complex entity -where there might be many potential values that need to be provided
+- the builder script can automatically default some or even all of these values.
 
-For example, for a customer's date of birth, this might default to a date making the customer an adult, aged between 18 and 65, say.
-For an email address or postal address, or an image, or some "lorem ipsum" text, the (non-ASF) link:http://platform.incode.org[Incode Platform^]'s fakedata module could for randomised values.
+For example, for a customer's date of birth, the buider could default to a date making the customer an adult, aged between 18 and 65, say.
+For an email address or postal address, or an image, or some "lorem ipsum" text, the (non-ASF) link:http://platform.incode.org[Incode Platform^]'s fakedata module could provide randomised values.
 
 The benefit of an intelligent builder is that it further simplifies the test.
 The developer reading the test then knows that everything that has been specified exactly is of significance.
-
+Because non-specified values are randomised and change on each run, it also decreases the chance that the test passes "by accident" (based on some lucky hard-coded input value).
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_clock-fixtures.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_ticking-clock-fixture.adoc
similarity index 60%
rename from adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_clock-fixtures.adoc
rename to adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_ticking-clock-fixture.adoc
index 9ba5959..179f864 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_clock-fixtures.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_ticking-clock-fixture.adoc
@@ -1,28 +1,24 @@
-[[_ugtst_fixture-scripts_clock-fixtures]]
-= Clock Fixtures (`1.16.0-SNAPSHOT`)
+[[_ugtst_fixture-scripts_ticking-clock-fixture]]
+= Ticking Clock Fixture (`1.16.0-SNAPSHOT`)
 :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 [...]
 :_basedir: ../../
 :_imagesdir: images/
 
 
 
-The `ClockFixture` is a pre-build fixture script that simply sets the time returned by the xref:../rgsvc/rgsvc.adoc#_rgsvc_api_ClockService[`ClockService`] to a known value.
+The `TickingClockFixture` is a pre-built fixture script that resets the date/time returned by the xref:../rgsvc/rgsvc.adoc#_rgsvc_api_ClockService[`ClockService`] to a known value.
+
+Thereafter the time returned continues to tick forward (as would the real clock) until reset once more.
 
 For example, to set the clock to return "3 Sept 2014", use:
 
 [source,java]
 ----
-executionContext.executeChild(this, ClockFixture.setTo("2014-09-03"));
+executionContext.executeChild(this, new TickingClockFixture().setTo("2014-09-03"));
 ----
 
 A variety of format strings are supported; the format "YYYY-MM-DD" (as shown above) will work in every locale.
 
-The fixture script requires that a `FixtureClock` is initialized.
-This happens automatically in any non-production environment, and in particular when running integration tests.
-
-
-The `TickingClockFixture` is another, slightly more sophisticated, fixture script.
-
-
+The fixture script requires that a `TickingFixtureClock` is initialized during bootstrapping.
+This is done automatically `IntegrationTestAbstract3` and `CukeGlueBootstrappingAbstract` (BDD specs).
 
-It requires that a TickingFixtureClock
\ No newline at end of file
diff --git a/core/applib/src/main/java/org/apache/isis/applib/clock/Clock.java b/core/applib/src/main/java/org/apache/isis/applib/clock/Clock.java
index 4ade764..90ae270 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/clock/Clock.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/clock/Clock.java
@@ -49,7 +49,7 @@ import org.apache.isis.applib.fixtures.FixtureClock;
  * {@link FixtureClock#getInstance()}.
  */
 public abstract class Clock {
-    static Clock instance;
+    protected static Clock instance;
     private static boolean isReplaceable = true;
 
     /**
diff --git a/core/applib/src/main/java/org/apache/isis/applib/clock/TickingFixtureClock.java b/core/applib/src/main/java/org/apache/isis/applib/fixtures/TickingFixtureClock.java
similarity index 98%
rename from core/applib/src/main/java/org/apache/isis/applib/clock/TickingFixtureClock.java
rename to core/applib/src/main/java/org/apache/isis/applib/fixtures/TickingFixtureClock.java
index d18e259..ae19ffd 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/clock/TickingFixtureClock.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixtures/TickingFixtureClock.java
@@ -16,11 +16,13 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.applib.clock;
+package org.apache.isis.applib.fixtures;
 
 import java.util.Calendar;
 import java.util.TimeZone;
 
+import org.apache.isis.applib.clock.Clock;
+
 public class TickingFixtureClock extends Clock {
     private static final TimeZone UTC_TIME_ZONE;
 
@@ -65,9 +67,7 @@ public class TickingFixtureClock extends Clock {
      * Makes {@link Clock#remove()} visible.
      */
     public static boolean reinstateExisting() {
-
         Clock.instance = existingInstance;
-
         return true;
     }
 
diff --git a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java
index 5862db6..fb9307f 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java
@@ -82,7 +82,6 @@ class ClockFixture extends FixtureScript implements FixtureScriptWithExecutionSt
                 "'%s' could not be parsed as a local date/time or local date", date));
     }
 
-    //region > parseAsLocalDateTime
     private static LocalDate parseAsLocalDate(String dateStr) {
         for (DateTimeFormatter formatter : new DateTimeFormatter[] {
                 DateTimeFormat.fullDateTime(),
diff --git a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java
index 2e6e6f7..8584f4e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java
@@ -18,9 +18,14 @@
  */
 package org.apache.isis.applib.fixturescripts.clock;
 
+import org.joda.time.LocalDate;
+import org.joda.time.LocalDateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
 import org.apache.isis.applib.clock.Clock;
-import org.apache.isis.applib.clock.TickingFixtureClock;
 import org.apache.isis.applib.fixtures.FixtureClock;
+import org.apache.isis.applib.fixtures.TickingFixtureClock;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.applib.fixturescripts.FixtureScriptWithExecutionStrategy;
 import org.apache.isis.applib.fixturescripts.FixtureScripts;
@@ -44,19 +49,85 @@ public class TickingClockFixture
     @Override
     protected void execute(ExecutionContext ec) {
 
+        // check that some value has been set
         checkParam("date", ec, String.class);
 
         final Clock instance = Clock.getInstance();
 
         if(instance instanceof TickingFixtureClock) {
-            TickingFixtureClock.reinstateExisting();
-            ec.executeChild(this, ClockFixture.setTo(date));
-            TickingFixtureClock.replaceExisting();
+            try {
+                TickingFixtureClock.reinstateExisting();
+                setTo(date);
+            } finally {
+                TickingFixtureClock.replaceExisting();
+            }
         }
 
         if(instance instanceof FixtureClock) {
-            ec.executeChild(this, ClockFixture.setTo(date));
+            setTo(date);
+        }
+    }
+
+    private void setTo(final String date) {
+
+        if (!(Clock.getInstance() instanceof FixtureClock)) {
+            throw new IllegalStateException("Clock has not been initialized as a FixtureClock");
+        }
+        final FixtureClock fixtureClock = (FixtureClock) FixtureClock.getInstance();
+
+        // process if can be parsed as a LocalDateTime
+        LocalDateTime ldt = parseAsLocalDateTime(date);
+        if (ldt != null) {
+            fixtureClock.setDate(ldt.getYear(), ldt.getMonthOfYear(), ldt.getDayOfMonth());
+            fixtureClock.setTime(ldt.getHourOfDay(), ldt.getMinuteOfHour());
+            return;
+        }
+
+        // else process if can be parsed as a LocalDate
+        LocalDate ld = parseAsLocalDate(date);
+        if (ld != null) {
+            fixtureClock.setDate(ld.getYear(), ld.getMonthOfYear(), ld.getDayOfMonth());
+            return;
+        }
+
+        // else
+        throw new IllegalArgumentException(String.format(
+                "'%s' could not be parsed as a local date/time or local date", date));
+
+    }
+
+    private static LocalDate parseAsLocalDate(String dateStr) {
+        for (DateTimeFormatter formatter : new DateTimeFormatter[] {
+                DateTimeFormat.fullDateTime(),
+                DateTimeFormat.mediumDateTime(),
+                DateTimeFormat.shortDateTime(),
+                DateTimeFormat.forPattern("yyyy-MM-dd"),
+                DateTimeFormat.forPattern("yyyyMMdd"),
+        }) {
+            try {
+                return formatter.parseLocalDate(dateStr);
+            } catch (Exception e) {
+                // continue;
+            }
+        }
+        return null;
+    }
+
+    private static LocalDateTime parseAsLocalDateTime(String dateStr) {
+        for (DateTimeFormatter formatter : new DateTimeFormatter[] {
+                DateTimeFormat.fullDateTime(),
+                DateTimeFormat.mediumDateTime(),
+                DateTimeFormat.shortDateTime(),
+                DateTimeFormat.forPattern("yyyyMMddhhmmss"),
+                DateTimeFormat.forPattern("yyyyMMddhhmm")
+        }) {
+            try {
+                return formatter.parseLocalDateTime(dateStr);
+            } catch (Exception e) {
+                // continue;
+            }
         }
+        return null;
     }
 
     @Override
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
index 834258b..adb1427 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
@@ -23,7 +23,7 @@ import javax.inject.Inject;
 import org.joda.time.LocalDate;
 
 import org.apache.isis.applib.clock.Clock;
-import org.apache.isis.applib.clock.TickingFixtureClock;
+import org.apache.isis.applib.fixtures.TickingFixtureClock;
 import org.apache.isis.applib.fixtures.FixtureClock;
 import org.apache.isis.applib.fixturescripts.BuilderScriptAbstract;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
index 94c05c3..6a7c0cb 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
@@ -30,7 +30,7 @@ import org.apache.isis.applib.AppManifest;
 import org.apache.isis.applib.AppManifest2;
 import org.apache.isis.applib.AppManifestAbstract2;
 import org.apache.isis.applib.Module;
-import org.apache.isis.applib.clock.TickingFixtureClock;
+import org.apache.isis.applib.fixtures.TickingFixtureClock;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.applib.fixturescripts.FixtureScripts;
 import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
diff --git a/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.java b/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.java
index 89f11f8..7df716b 100644
--- a/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.java
+++ b/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.java
@@ -25,7 +25,7 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.services.i18n.TranslatableString;
 
 import domainapp.modules.simple.dom.impl.SimpleObject;
-import domainapp.modules.simple.dom.impl.SimpleObjectRepository;
+import domainapp.modules.simple.dom.impl.SimpleObjects;
 
 @DomainObject(
         nature = Nature.VIEW_MODEL,
@@ -38,9 +38,9 @@ public class HomePageViewModel {
     }
 
     public List<SimpleObject> getObjects() {
-        return simpleObjectRepository.listAll();
+        return simpleObjects.listAll();
     }
 
     @javax.inject.Inject
-    SimpleObjectRepository simpleObjectRepository;
+    SimpleObjects simpleObjects;
 }
diff --git a/example/application/simpleapp/application/src/test/java/domainapp/application/integtests/Smoke_IntegTest.java b/example/application/simpleapp/application/src/test/java/domainapp/application/integtests/Smoke_IntegTest.java
index b724fb9..aedc1b3 100644
--- a/example/application/simpleapp/application/src/test/java/domainapp/application/integtests/Smoke_IntegTest.java
+++ b/example/application/simpleapp/application/src/test/java/domainapp/application/integtests/Smoke_IntegTest.java
@@ -24,35 +24,17 @@ import javax.inject.Inject;
 
 import org.junit.Test;
 
-import org.apache.isis.applib.AppManifest2;
-import org.apache.isis.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.applib.services.metamodel.MetaModelService4;
-import org.apache.isis.applib.services.xactn.TransactionService;
-
 import domainapp.modules.simple.dom.impl.SimpleObject;
-import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
+import domainapp.modules.simple.dom.impl.SimpleObjects;
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class Smoke_IntegTest extends DomainAppIntegTestAbstract {
 
     @Inject
-    FixtureScripts fixtureScripts;
-    @Inject
-    TransactionService transactionService;
-    @Inject
-    SimpleObjectMenu menu;
-
-    @Inject
-    MetaModelService4 metaModelService4;
+    SimpleObjects menu;
 
     @Test
-    public void create() throws Exception {
-
-        // given
-        AppManifest2 appManifest2 = metaModelService4.getAppManifest2();
-        fixtureScripts.runFixtureScript(appManifest2.getTeardownFixture(), null);
-        transactionService.nextTransaction();
-
+    public void create() {
 
         // when
         List<SimpleObject> all = wrap(menu).listAll();
@@ -92,7 +74,6 @@ public class Smoke_IntegTest extends DomainAppIntegTestAbstract {
         assertThat(wrap(fred).getName()).isEqualTo("Freddy");
 
 
-
         // when
         wrap(fred).setNotes("These are some notes");
 
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjectRepository.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjectRepository.java
deleted file mode 100644
index 8e2fc91..0000000
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjectRepository.java
+++ /dev/null
@@ -1,69 +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.
- */
-package domainapp.modules.simple.dom.impl;
-
-import java.util.List;
-
-import org.datanucleus.query.typesafe.TypesafeQuery;
-
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
-import org.apache.isis.applib.services.repository.RepositoryService;
-
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        repositoryFor = SimpleObject.class
-)
-public class SimpleObjectRepository {
-
-    public List<SimpleObject> listAll() {
-        return repositoryService.allInstances(SimpleObject.class);
-    }
-
-    public List<SimpleObject> findByName(final String name) {
-        TypesafeQuery<SimpleObject> q = isisJdoSupport.newTypesafeQuery(SimpleObject.class);
-        final QSimpleObject cand = QSimpleObject.candidate();
-        q = q.filter(
-                cand.name.indexOf(q.stringParameter("name")).ne(-1)
-        );
-        return q.setParameter("name", name)
-                .executeList();
-    }
-
-    public SimpleObject findByNameExact(final String name) {
-        TypesafeQuery<SimpleObject> q = isisJdoSupport.newTypesafeQuery(SimpleObject.class);
-        final QSimpleObject cand = QSimpleObject.candidate();
-        q = q.filter(
-                cand.name.eq(q.stringParameter("name"))
-        );
-        return q.setParameter("name", name)
-                .executeUnique();
-    }
-
-    public SimpleObject create(final String name) {
-        return repositoryService.persist(new SimpleObject(name));
-    }
-
-    @javax.inject.Inject
-    RepositoryService repositoryService;
-
-    @javax.inject.Inject
-    IsisJdoSupport isisJdoSupport;
-}
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjectMenu.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjects.java
similarity index 65%
rename from example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjectMenu.java
rename to example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjects.java
index 79b209a..f216f8a 100644
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjectMenu.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObjects.java
@@ -20,7 +20,7 @@ package domainapp.modules.simple.dom.impl;
 
 import java.util.List;
 
-import javax.inject.Inject;
+import org.datanucleus.query.typesafe.TypesafeQuery;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
@@ -30,9 +30,11 @@ import org.apache.isis.applib.annotation.DomainServiceLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.ParameterLayout;
+import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
-import org.apache.isis.applib.services.message.MessageService;
+import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
+import org.apache.isis.applib.services.repository.RepositoryService;
 
 @DomainService(
         nature = NatureOfService.VIEW_MENU_ONLY,
@@ -43,13 +45,13 @@ import org.apache.isis.applib.services.message.MessageService;
         named = "Simple Objects",
         menuOrder = "10"
 )
-public class SimpleObjectMenu {
+public class SimpleObjects {
 
     @Action(semantics = SemanticsOf.SAFE)
     @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
     @MemberOrder(sequence = "1")
     public List<SimpleObject> listAll() {
-        return simpleObjectRepository.listAll();
+        return repositoryService.allInstances(SimpleObject.class);
     }
 
 
@@ -60,21 +62,40 @@ public class SimpleObjectMenu {
             @ParameterLayout(named="Name")
             final String name
     ) {
-        return simpleObjectRepository.findByName(name);
+        TypesafeQuery<SimpleObject> q = isisJdoSupport.newTypesafeQuery(SimpleObject.class);
+        final QSimpleObject cand = QSimpleObject.candidate();
+        q = q.filter(
+                cand.name.indexOf(q.stringParameter("name")).ne(-1)
+        );
+        return q.setParameter("name", name)
+                .executeList();
+    }
+
+    @Programmatic
+    public SimpleObject findByNameExact(final String name) {
+        TypesafeQuery<SimpleObject> q = isisJdoSupport.newTypesafeQuery(SimpleObject.class);
+        final QSimpleObject cand = QSimpleObject.candidate();
+        q = q.filter(
+                cand.name.eq(q.stringParameter("name"))
+        );
+        return q.setParameter("name", name)
+                .executeUnique();
     }
 
 
-    public static class CreateDomainEvent extends ActionDomainEvent<SimpleObjectMenu> {}
+    public static class CreateDomainEvent extends ActionDomainEvent<SimpleObjects> {}
     @Action(domainEvent = CreateDomainEvent.class)
     @MemberOrder(sequence = "3")
     public SimpleObject create(
             @ParameterLayout(named="Name")
             final String name) {
-        return simpleObjectRepository.create(name);
+        return repositoryService.persist(new SimpleObject(name));
     }
 
+    @javax.inject.Inject
+    RepositoryService repositoryService;
 
     @javax.inject.Inject
-    SimpleObjectRepository simpleObjectRepository;
+    IsisJdoSupport isisJdoSupport;
 
 }
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObjectBuilder.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObjectBuilder.java
index bda6adb..b6647ef 100644
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObjectBuilder.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObjectBuilder.java
@@ -22,7 +22,7 @@ package domainapp.modules.simple.fixture;
 import org.apache.isis.applib.fixturescripts.BuilderScriptAbstract;
 
 import domainapp.modules.simple.dom.impl.SimpleObject;
-import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
+import domainapp.modules.simple.dom.impl.SimpleObjects;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.experimental.Accessors;
@@ -41,10 +41,10 @@ public class SimpleObjectBuilder extends BuilderScriptAbstract<SimpleObject, Sim
 
         checkParam("name", ec, String.class);
 
-        object = wrap(simpleObjectMenu).create(name);
+        object = wrap(simpleObjects).create(name);
     }
 
     @javax.inject.Inject
-    SimpleObjectMenu simpleObjectMenu;
+    SimpleObjects simpleObjects;
 
 }
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
index 35506fa..2cd09a3 100644
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
@@ -25,7 +25,7 @@ import org.apache.isis.applib.fixturescripts.setup.PersonaEnumPersistAll;
 import org.apache.isis.applib.services.registry.ServiceRegistry2;
 
 import domainapp.modules.simple.dom.impl.SimpleObject;
-import domainapp.modules.simple.dom.impl.SimpleObjectRepository;
+import domainapp.modules.simple.dom.impl.SimpleObjects;
 import lombok.AllArgsConstructor;
 
 @AllArgsConstructor
@@ -52,8 +52,8 @@ public enum SimpleObject_persona implements PersonaWithBuilderScript<SimpleObjec
 
     @Override
     public SimpleObject findUsing(final ServiceRegistry2 serviceRegistry) {
-        SimpleObjectRepository simpleObjectRepository = serviceRegistry.lookupService(SimpleObjectRepository.class);
-        return simpleObjectRepository.findByNameExact(name);
+        SimpleObjects simpleObjects = serviceRegistry.lookupService(SimpleObjects.class);
+        return simpleObjects.findByNameExact(name);
     }
 
     public static class PersistAll
diff --git a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjectRepository_Test.java b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjects_Test.java
similarity index 82%
rename from example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjectRepository_Test.java
rename to example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjects_Test.java
index 609151e..2072037 100644
--- a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjectRepository_Test.java
+++ b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/dom/impl/SimpleObjects_Test.java
@@ -36,7 +36,7 @@ import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-public class SimpleObjectRepository_Test {
+public class SimpleObjects_Test {
 
     @Rule
     public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
@@ -44,18 +44,18 @@ public class SimpleObjectRepository_Test {
     @Mock
     RepositoryService mockRepositoryService;
 
-    SimpleObjectRepository simpleObjectRepository;
+    SimpleObjects simpleObjects;
 
     @Before
-    public void setUp() throws Exception {
-        simpleObjectRepository = new SimpleObjectRepository();
-        simpleObjectRepository.repositoryService = mockRepositoryService;
+    public void setUp() {
+        simpleObjects = new SimpleObjects();
+        simpleObjects.repositoryService = mockRepositoryService;
     }
 
-    public static class Create extends SimpleObjectRepository_Test {
+    public static class Create extends SimpleObjects_Test {
 
         @Test
-        public void happyCase() throws Exception {
+        public void happyCase() {
 
             final String someName = "Foobar";
 
@@ -69,7 +69,7 @@ public class SimpleObjectRepository_Test {
             });
 
             // when
-            final SimpleObject obj = simpleObjectRepository.create(someName);
+            final SimpleObject obj = simpleObjects.create(someName);
 
             // then
             assertThat(obj).isNotNull();
@@ -91,10 +91,10 @@ public class SimpleObjectRepository_Test {
         }
     }
 
-    public static class ListAll extends SimpleObjectRepository_Test {
+    public static class ListAll extends SimpleObjects_Test {
 
         @Test
-        public void happyCase() throws Exception {
+        public void happyCase() {
 
             // given
             final List<SimpleObject> all = Lists.newArrayList();
@@ -107,7 +107,7 @@ public class SimpleObjectRepository_Test {
             });
 
             // when
-            final List<SimpleObject> list = simpleObjectRepository.listAll();
+            final List<SimpleObject> list = simpleObjects.listAll();
 
             // then
             assertThat(list).isEqualTo(all);
diff --git a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java
index 04d3914..49d6ff3 100644
--- a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java
+++ b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java
@@ -31,7 +31,7 @@ import org.hamcrest.TypeSafeMatcher;
 import org.junit.Test;
 
 import domainapp.modules.simple.dom.impl.SimpleObject;
-import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
+import domainapp.modules.simple.dom.impl.SimpleObjects;
 import domainapp.modules.simple.fixture.SimpleObject_persona;
 import domainapp.modules.simple.integtests.SimpleModuleIntegTestAbstract;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -114,6 +114,6 @@ public class SimpleObjectMenu_IntegTest extends SimpleModuleIntegTestAbstract {
     }
 
     @Inject
-    SimpleObjectMenu menu;
+    SimpleObjects menu;
 
 }
\ No newline at end of file
diff --git a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java
index a960df2..cfa78b7 100644
--- a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java
+++ b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java
@@ -26,7 +26,7 @@ import org.apache.isis.core.specsupport.specs.CukeGlueAbstract2;
 import cucumber.api.java.en.Given;
 import cucumber.api.java.en.When;
 import domainapp.modules.simple.dom.impl.SimpleObject;
-import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
+import domainapp.modules.simple.dom.impl.SimpleObjects;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
@@ -34,16 +34,16 @@ public class SimpleObjectMenuGlue extends CukeGlueAbstract2 {
 
     @Given("^there are.* (\\d+) simple objects$")
     public void there_are_N_simple_objects(int n) throws Throwable {
-        final List<SimpleObject> list = wrap(simpleObjectMenu).listAll();
+        final List<SimpleObject> list = wrap(simpleObjects).listAll();
         assertThat(list.size(), is(n));
     }
     
     @When("^.*create a .*simple object$")
     public void create_a_simple_object() throws Throwable {
-        wrap(simpleObjectMenu).create(UUID.randomUUID().toString());
+        wrap(simpleObjects).create(UUID.randomUUID().toString());
     }
 
     @Inject
-    SimpleObjectMenu simpleObjectMenu;
+    SimpleObjects simpleObjects;
 
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.

[isis] 01/02: ISIS-1791: tidies up ClockFixture, TickingClockFixture, updates docs.

Posted by da...@apache.org.
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/isis.git

commit 8dc422c7578077fa278538163a484edf14187799
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Tue Dec 19 16:46:51 2017 +0000

    ISIS-1791: tidies up ClockFixture, TickingClockFixture, updates docs.
    
    Also fixes simpleapp fixtures
---
 ..._ugfun_getting-started_simpleapp-archetype.adoc |   2 +
 .../guides/ugtst/_ugtst_bdd-spec-support.adoc      |   1 -
 .../guides/ugtst/_ugtst_fixture-scripts.adoc       |  18 +-
 .../_ugtst_fixture-scripts_api-and-usage.adoc      | 318 ++++++++++-----------
 .../_ugtst_fixture-scripts_clock-fixtures.adoc     |  28 ++
 .../ugtst/_ugtst_fixture-scripts_sudo-service.adoc |   6 +-
 .../images/testing/fixture-scripts/prompt.png      | Bin 52869 -> 49181 bytes
 .../testing/fixture-scripts/prototyping-menu.png   | Bin 59183 -> 58104 bytes
 .../result-list-specifying-number.png              | Bin 63100 -> 0 bytes
 .../images/testing/fixture-scripts/result-list.png | Bin 50272 -> 82117 bytes
 .../apache/isis/applib/AppManifestAbstract.java    |  10 +-
 .../applib/fixturescripts/clock/ClockFixture.java  |  92 +++---
 .../fixturescripts/clock/TickingClockFixture.java  |  26 +-
 .../application/manifest/DomainAppAppManifest.java |  12 +-
 .../manifest/DomainAppAppManifestWithFixtures.java |   7 +-
 .../services/homepage/HomePageViewModel.layout.xml |   1 +
 .../domainapp/modules/simple/SimpleModule.java     |   7 -
 .../simple/fixture/SimpleObject_persona.java       |   8 +
 .../tests/SimpleObjectMenu_IntegTest.java          |  62 +---
 .../integtests/tests/SimpleObject_IntegTest.java   |  32 +--
 20 files changed, 319 insertions(+), 311 deletions(-)

diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc
index deb3cad..47a1627 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_getting-started_simpleapp-archetype.adoc
@@ -270,6 +270,8 @@ The BDD specs and integration tests are named according to the naming convention
 
 === myapp-module-simple
 
+NOTE: this is out of date for 1.16.0-SNAPSHOT
+
 This module is where the domain object model lives, that is the business logic of the application itself.
 This typically comprises entities, domain services, mixins and view models.
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_bdd-spec-support.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_bdd-spec-support.adoc
index f1c308d..991dbd9 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_bdd-spec-support.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_bdd-spec-support.adoc
@@ -13,7 +13,6 @@ There are many BDD tools out there; Apache Isis provides an integration with lin
 
 
 include::_ugtst_bdd-spec-support_how-it-works.adoc[leveloffset=+1]
-include::_ugtst_bdd-spec-support_key-classes.adoc[leveloffset=+1]
 include::_ugtst_bdd-spec-support_writing-a-bdd-spec.adoc[leveloffset=+1]
 include::_ugtst_bdd-spec-support_maven-configuration.adoc[leveloffset=+1]
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc
index 2acc6ee..faa37d0 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts.adoc
@@ -6,20 +6,27 @@
 
 
 
-When writing integration tests (and implementing the glue for BDD specs) it can be difficult to keep the "given" short; there could be a lot of prerequisite data that needs to exist before you can actually exercise your system.  Moreover, however we do set up that data, but we also want to do so in a way that is resilient to the system changing over time.
+When writing integration tests (and implementing the glue for BDD specs) it can be difficult to keep the "given" short; there could be a lot of prerequisite data that needs to exist before you can actually exercise your system.
+Moreover, however we do set up that data, but we also want to do so in a way that is resilient to the system changing over time.
 
-On a very simple system you could probably get away with using SQL to insert directly into the database, or you could use a toolkit such as link:http://dbunit.sourceforge.net/howto.html[dbunit] to upload data from flat files.  Such approaches aren't particularly maintainable though.  If in the future the domain entities (and therefore corresponding database tables) change their structure, then all of those data sets will need updating.
+On a very simple system you could probably get away with using SQL to insert directly into the database, or you could use a toolkit such as link:http://dbunit.sourceforge.net/howto.html[dbunit] to upload data from flat files.
+Such approaches aren't particularly maintainable though.
+If in the future the domain entities (and therefore corresponding database tables) change their structure, then all of those data sets will need updating.
 
-Even more significantly, there's no way to guarantee that the data that's being loaded is logically consistent with the business behaviour of the domain objects themselves.  That is, there's nothing to stop your test from putting data into the database that would be invalid if one attempted to add it through the app.
+Even more significantly, there's no way to guarantee that the data that's being loaded is logically consistent with the business behaviour of the domain objects themselves.
+That is, there's nothing to stop your test from putting data into the database that would be invalid if one attempted to add it through the app.
 
-The solution that Apache Isis provides is a small library called *_fixture scripts_*.  A fixture script is basically a wrapper for executing arbitrary work, but that work almost always invoking a business action.
+The solution that Apache Isis provides is a small library called *_fixture scripts_*.
+A fixture script is basically a command object for executing arbitrary work, where the work in question is almost always invoking one or more business actions.
+In other words, the database is populating through the functionality of the domain object model itself.
 
 [TIP]
 ====
 If you want to learn more on this topic (with live coding!), check out this https://skillsmatter.com/skillscasts/5638-to-those-whom-much-is-given-much-is-expected[presentation] given at BDD Exchange 2014.
 ====
 
-There is another benefit to Apache Isis' fixture script approach; the fixtures can be (in prototyping mode) run from your application.  This means that fixture scripts can actually help all the way through the development lifecycle:
+There is another benefit to Apache Isis' fixture script approach; the fixtures can be (in prototyping mode) run from your application.
+This means that fixture scripts can actually help all the way through the development lifecycle:
 
 * when specifying a new feature, you can write a fixture script to get the system into the "given" state, and then start exploring the required functionality with the domain expert actually _within_ the application +
 +
@@ -40,5 +47,6 @@ The following  sections explain the API and how to go about using the API.
 
 
 include::_ugtst_fixture-scripts_api-and-usage.adoc[leveloffset=+1]
+include::_ugtst_fixture-scripts_clock-fixtures.adoc[leveloffset=+1]
 include::_ugtst_fixture-scripts_sudo-service.adoc[leveloffset=+1]
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc
index 54c795b..200a9f6 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_api-and-usage.adoc
@@ -5,7 +5,7 @@
 :_imagesdir: images/
 
 
-There are two parts to using fixture scripts: the `FixtureScripts` domain service class, and the `FixtureScript` view model class:
+There are two main parts to using fixture scripts: the `FixtureScripts` domain service class, and the `FixtureScript` view model class:
 
 * 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.
 
@@ -16,34 +16,26 @@ Let's look at `FixtureScripts` domain service in more detail first.
 
 == `FixtureScripts`
 
-There are two ways in which you can provide a `FixtureScripts` service.
+The framework provides a default implementation of `FixtureScripts` domain service, namely the xref:../rgsvc/rgsvc.adoc#_rgsvc_testing_FixtureScriptsDefault[`FixtureScriptsDefault`] domain service.
+This is annotated to be rendered on the secondary "Prototyping" menu.
 
-The original (pre-`1.9.0`) approach is to subclass subclass `FixtureScripts` domain service, with your subclass specifying which package to search for.
-Various other settings can also be provided, and - being a custom class - you can also add in additional actions.
-A common example is to provide a "one-shot" action to recreate a standard demo set of objects.
-
-As of `1.9.0` there is an alternative design.
-Instead of subclassing `FixtureScripts` you instead implement the xref:../rgsvc/rgsvc.adoc#_rgsvc_testing_FixtureScriptsSpecificationProvider[`FixtureScriptsSpecificationProvider`] SPI.
-(As its name suggests), this provides a `FixtureScriptsSpecification` object that contains the same information as would otherwise have been in the `FixtureScripts` subclass.
-
-The actual implementation of the `FixtureScripts` service is then provided by the framework itself, namely the xref:../rgsvc/rgsvc.adoc#_rgsvc_testing_FixtureScriptsDefault[`FixtureScriptsDefault`] domain service, annotated to be rendered on the secondary "Prototyping" menu.
-This uses the `FixtureScriptsSpecificationProvider` to adjust itself accordinly.
+The behaviour of this domain menu service can be refined by providing an implementation of the optional xref:../rgsvc/rgsvc.adoc#_rgsvc_testing_FixtureScriptsSpecificationProvider[`FixtureScriptsSpecificationProvider`] SPI.
 
 For example, here's the `FixtureScriptsSpecificationProvider` service that's generated by the xref:../ugfun/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype]:
 
 [source,java]
 ----
-@DomainService(nature = NatureOfService.DOMAIN)
-public class DomainAppFixturesProvider implements FixtureScriptsSpecificationProvider {
-    @Override
+@DomainService( nature = NatureOfService.DOMAIN )
+public class DomainAppFixtureScriptsSpecificationProvider
+                    implements FixtureScriptsSpecificationProvider {
     public FixtureScriptsSpecification getSpecification() {
         return FixtureScriptsSpecification
-                .builder(DomainAppFixturesProvider.class)                                       // <1>
-                .with(FixtureScripts.MultipleExecutionStrategy.EXECUTE)                         // <2>
-                .withRunScriptDefault(RecreateSimpleObjects.class)                              // <3>
-                .withRunScriptDropDown(FixtureScriptsSpecification.DropDownPolicy.CHOICES)      // <4>
-                .withRecreate(RecreateSimpleObjects.class)                                      // <5>
-                .build();
+            .builder(DomainAppFixtureScriptsSpecificationProvider.class)               // <1>
+            .with(FixtureScripts.MultipleExecutionStrategy.EXECUTE)                    // <2>
+            .withRunScriptDefault(DomainAppDemo.class)                                 // <3>
+            .withRunScriptDropDown(FixtureScriptsSpecification.DropDownPolicy.CHOICES) // <4>
+            .withRecreate(DomainAppDemo.class)                                         // <5>
+            .build();
     }
 }
 ----
@@ -54,50 +46,10 @@ public class DomainAppFixturesProvider implements FixtureScriptsSpecificationPro
 <5> if present, enables a "recreate objects and return first" action to be displayed in the UI
 
 
-The benefit of this design - decoupling the responsibilities of the superclass and the subclass - is that it ensures that there is always an instance of `FixtureScripts` available, even if the application itself doesn't provide one.
-.
-
-By way of comparison, if using the older pre-`1.9.0` approach then you would create a subclass:
-
-[source,java]
-----
-@DomainService
-@DomainServiceLayout(
-        menuBar = DomainServiceLayout.MenuBar.SECONDARY,           // <1>
-        named="Prototyping",                                       // <2>
-        menuOrder = "500"
-)
-public class DomainAppFixturesService extends FixtureScripts {     // <3>
-    public DomainAppFixturesService() {
-        super(
-            "domainapp",                                           // <4>
-            MultipleExecutionStrategy.EXECUTE);                    // <5>
-    }
-    @Override
-    public FixtureScript default0RunFixtureScript() {
-        return findFixtureScriptFor(RecreateSimpleObjects.class);  // <6>
-    }
-    @Override
-    public List<FixtureScript> choices0RunFixtureScript() {        // <7>
-        return super.choices0RunFixtureScript();
-    }
-}
-----
-<1> in the UI, render the on the right hand side (secondary) menu bar...
-<2> ... under the "Prototyping" menu
-<3> inherit from `org.apache.isis.applib.fixturescripts.FixtureScripts`
-<4> search for all fixture scripts under the "domainapp" package; in your code this would probably be "com.mycompany.myapp" or similar
-<5> if the same fixture script (class) is encountered more than once, then run anyway; more on this in xref:../ugtst/ugtst.adoc#__ugtst_fixture-scripts_api-and-usage_organizing[Organizing Fixture scripts]], below.
-<6> (optional) specify a default fixture script to run, in this case `RecreateSimpleObjects` fixture script (see below)
-<7> make all fixture scripts found available as a drop-down (by increasing the visibility of this method to `public`)
-
-This isn't quite equivalent; you would need to write additional code to support the "recreate objects and return first" action, for example.
-
-Either way, here's how the domain service looks like in the UI:
+Here's how the domain service looks like in the UI:
 
 image::{_imagesdir}testing/fixture-scripts/prototyping-menu.png[width="700px",link="{_imagesdir}testing/fixture-scripts/prototyping-menu.png"]
 
-
 and here's what the `runFixtureScript` action prompt looks like:
 
 image::{_imagesdir}testing/fixture-scripts/prompt.png[width="700px",link="{_imagesdir}testing/fixture-scripts/prompt.png"]
@@ -148,10 +100,12 @@ A fixture script is ultimately just a block of code that can be executed, so it'
 However, we strongly recommend that you use it to invoke actions on business objects, in essence to replay what a real-life user would have done.
 That way, the fixture script will remain valid even if the underlying implementation of the system changes in the future.
 
-Here's the `RecreateSimpleObjects` fixture script from the xref:../ugfun/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype]:
+For example, here's a fixture script called `RecreateSimpleObjects`.
+(This used to be part of the xref:../ugfun/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype], though the archetype now ships with a more sophisticated design, discussed below):
 
 [source,java]
 ----
+@lombok.Accessors(chain = true)
 public class RecreateSimpleObjects extends FixtureScript {                   // <1>
 
     public final List<String> NAMES = Collections.unmodifiableList(Arrays.asList(
@@ -160,16 +114,13 @@ public class RecreateSimpleObjects extends FixtureScript {                   //
     public RecreateSimpleObjects() {
         withDiscoverability(Discoverability.DISCOVERABLE);                   // <3>
     }
+
+    @lombok.Getter @lombok.Setter
     private Integer number;                                                  // <4>
-    public Integer getNumber() { return number; }
-    public RecreateSimpleObjects setNumber(final Integer number) {
-        this.number = number;
-        return this;
-    }
+
+    @lombok.Getter
     private final List<SimpleObject> simpleObjects = Lists.newArrayList();   // <5>
-    public List<SimpleObject> getSimpleObjects() {
-        return simpleObjects;
-    }
+
     @Override
     protected void execute(final ExecutionContext ec) {          // <6>
         // defaults
@@ -208,55 +159,10 @@ Note that although the fixture script is a view model, it's fine to simply insta
 Because this script has exposed a "number" property, it's possible to set this from within the UI.
 For example:
 
-image::{_imagesdir}testing/fixture-scripts/prompt.png[width="700px",link="{_imagesdir}testing/fixture-scripts/prompt.png"]
+image::{_imagesdir}testing/fixture-scripts/prompt-specifying-number.png[width="700px",link="{_imagesdir}testing/fixture-scripts/prompt-specifying-number.png"]
 
 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:
-
-image::{_imagesdir}testing/fixture-scripts/result-list.png[width="700px",link="{_imagesdir}testing/fixture-scripts/result-list.png"]
-
-
-
-It's commonplace for one fixture script to call another.
-In the above example this script called `SimpleObjectsTearDown` and `SimpleObjectCreate`.
-Let's take a quick look at `SimpleObjectCreate`:
-
-[source,java]
-----
-public class SimpleObjectCreate extends FixtureScript {       // <1>
-
-    private String name;                                      // <2>
-    public String getName() { return name; }
-    public SimpleObjectCreate setName(final String name) {
-        this.name = name;
-        return this;
-    }
-    private SimpleObject simpleObject;                        // <3>
-    public SimpleObject getSimpleObject() {
-        return simpleObject;
-    }
-    @Override
-    protected void execute(final ExecutionContext ec) {       // <4>
-        String name = checkParam("name", ec, String.class);   // <5>
-        this.simpleObject = wrap(simpleObjects)               // <6>
-                                .create(name);                // <7>
-        ec.addResult(this, simpleObject);                     // <8>
-    }
-    @javax.inject.Inject
-    private SimpleObjects simpleObjects;                      // <9>
-}
-----
-<1> inherit from `org.apache.isis.applib.fixturescripts.FixtureScript`, as above
-<2> input property: name of the object; this time it is required
-<3> output property: the created simple object
-<4> the mandatory execute(...) API
-<5> the `checkParam(...)` (inherited from `FixtureScript`) will check that the "name" property has been populated (using Java's Reflection API) and throw an exception if not
-<6> wrap the injected `SimpleObjects` domain service (using the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_WrapperFactory[`WrapperFactory`]) to simulate interaction through the UI...
-<7> .. and actually create the object using the "create" business action of that service
-<8> add the resulting object to the execution context; this makes the object available to access if run from the UI
-<9> inject the domain service into the fixture script
-
-
+So, in this case, when the fixture script is executed we actually get 6 objects created.
 
 
 
@@ -269,8 +175,6 @@ For example, here's an integration test from the xref:../ugfun/ugfun.adoc#_ugfun
 [source,java]
 ----
 public class SimpleObjectIntegTest extends SimpleAppIntegTest {
-    @Inject
-    FixtureScripts fixtureScripts;                      // <1>
     SimpleObject simpleObjectWrapped;
     @Before
     public void setUp() throws Exception {
@@ -283,7 +187,7 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest {
             fs.getSimpleObjects().get(0);               // <4>
         assertThat(simpleObjectPojo).isNotNull();
 
-        simpleObjectWrapped = wrap(simpleObjectPojo);   // <5>
+        simpleObjectWrapped = wrap(simpleObjectPojo);   // <4>
     }
     @Test
     public void accessible() throws Exception {
@@ -293,72 +197,162 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest {
         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)
+
+
+
+== "Persona" Builder Scripts (`1.16.0-SNAPSHOT`)
+
+Good integration tests are probably the best way to understand the behaviour of the domain model: better than reading the code itself.
+Such tests should clearly separating out the "given", from the "when", from the "then".
+The "given" - the initial data set - should be as minimal as possible so that the developer reading the test knows that everything being set up is essential to the functionality under test.
+
+"Persona" instances of entity classes help the developer become familiar with the data being set up.
+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.
+So, going back to the previous example, we might have:
+
+[source,xml]
+----
+public enum Customer_persona
+        implements PersonaWithBuilderScript<..>, PersonaWithFinder<..> {
+
+    SteveSingle("Steve", "Single", 21, MaritalStatus.SINGLE, 0)
+    MeghanMarriedMum("Meghan", "Married-Mum", 35, MaritalStatus.MARRIED, 2);
+    ...
 }
 ----
-<1> inject the `FixtureScripts` domain service (just like any other domain service)
-<2> instantiate the fixture script for this test, and configure
-<3> execute the fixture script
-<4> obtain the object under test from the fixture
-<5> wrap the object (to simulate being interacted with through the UI)
 
+The `PersonaWithBuilderScript` interface means that this enum is able to act as a factory for a `BuilderScriptAbstract`.
+This is a specialization of `FixtureScript` that is used to actually create the entity (customer, or whatever), using the data taken out of the enum instance:
 
+[source,xml]
+----
+public interface PersonaWithBuilderScript<T, F extends BuilderScriptAbstract<T,F>>  {
+    F builder();
+}
+----
 
+The `PersonaWithFinder` interface meanwhile indicates that the enum can "lookup" its corresponding entity from the appropriate repository domain service:
 
-[[__ugtst_fixture-scripts_api-and-usage_organizing]]
-== Organizing Fixture scripts
+[source,xml]
+----
+public interface PersonaWithFinder<T> {
+    T findUsing(final ServiceRegistry2 serviceRegistry);
 
-There are lots of ways to organize fixture scripts, but we've used them as either:
+}
+----
 
-* a fairly flat style, eg as in the xref:../ugfun/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype], also as in the http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp];
+(As of `1.16.0-SNAPSHOT`) the xref:../ugfun/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype] provides a sample implementation of these interfaces:
 
-* in a "composite pattern" style, eg as in the https://github.com/estatio/estatio/blob/ea20a6ce257acede50de6ce4fd2ff29713fcd689/estatioapp/fixture/src/main/java/org/estatio/fixture/invoice/InvoiceForLeaseItemTypeOfDiscountOneQuarterForOxfMiracle005.java#L66)[Estatio open source app].
+[source,java]
+----
+@lombok.AllArgsConstructor
+public enum SimpleObject_persona
+        implements PersonaWithBuilderScript<SimpleObject, SimpleObjectBuilder>,
+                   PersonaWithFinder<SimpleObject> {
+    FOO("Foo"),
+    BAR("Bar"),
+    BAZ("Baz"),
+    FRODO("Frodo"),
+    FROYO("Froyo"),
+    FIZZ("Fizz"),
+    BIP("Bip"),
+    BOP("Bop"),
+    BANG("Bang"),
+    BOO("Boo");
+
+    private final String name;
 
-These two styles are probably best illustrated with, well, some illustrations.
-Here's a fixture script in the "flat" style for setting up a customer with some orders, a number of which has been placed:
+    @Override
+    public SimpleObjectBuilder builder() {
+        return new SimpleObjectBuilder().setName(name);
+    }
 
-image::{_imagesdir}testing/fixture-scripts/flat-1.png[width="700px",link="{_imagesdir}testing/fixture-scripts/flat-1.png"]
+    @Override
+    public SimpleObject findUsing(final ServiceRegistry2 serviceRegistry) {
+        SimpleObjectRepository simpleObjectRepository =
+            serviceRegistry.lookupService(SimpleObjectRepository.class);
+        return simpleObjectRepository.findByNameExact(name);
+    }
+}
+----
 
-Notice how we have a single script that's in control of the overall process, and takes responsibility for passing data from one fixture script to the next.
+where `SimpleObjectBuilder` in turn is:
 
-Here's a similar, simpler script, from the same fictional app, to set up two customers:
+[source,java]
+----
+@lombok.Accessors(chain = true)
+public class SimpleObjectBuilder
+            extends BuilderScriptAbstract<SimpleObject, SimpleObjectBuilder> {
 
-image::{_imagesdir}testing/fixture-scripts/flat-2.png[width="500px",link="{_imagesdir}testing/fixture-scripts/flat-2.png"]
+    @lombok.Getter @lombok.Setter
+    private String name;                                    // <1>
 
-We can reuse the same fixture "customer" script, either calling it twice or (perhaps better) passing it an array of customer details to set up.
+    @Override
+    protected void execute(final ExecutionContext ec) {
+        checkParam("name", ec, String.class);               // <2>
+        object = wrap(simpleObjectMenu).create(name);
+    }
 
-With the composite style, we rely on each fixture script to set up its own prerequisites.
-Thus:
+    @lombok.Getter
+    private SimpleObject object;                            // <3>
+
+    @javax.inject.Inject
+    SimpleObjectMenu simpleObjectMenu;
+}
+----
+<1> The persona class should set this value (copied from its own state)
+<2> the inherited "checkParam" is used to ensure that a value is set
+<3> the created entity is provided as an output
 
-image::{_imagesdir}testing/fixture-scripts/composite.png[width="550px",link="{_imagesdir}testing/fixture-scripts/composite.png"]
 
-Back in the earlier section we noted the `MultipleExecutionStrategy` setting.
-We can now explain the meaning of this: the enum value of `EXECUTE` is designed for the flat style (where every fixture script will be called), whereas the enum value of `IGNORE` is designed for the composite style, and ensures that any fixture scripts visited more than once (eg TearDown) are only every executed the first time.
+This simplifies the integration tests considerably:
+
+[source,java]
+----
+public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
 
-As already noted , the app generated by the xref:../ugfun/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype] uses the flat structure, and we feel that it's a better at separating out the "how" (how we set up some graph of domain objects into a known state, eg a customer with shipped placed orders and a newly placed order) from the "what" (what data should we actually use for the customer's name, say).
+    SimpleObject simpleObject;
 
-The composite style tends to combine these, which one could argue does not separate responsibilities well enough.
-On the other hand, one could also make an argument that the composite style is a good way to implement precanned personas, eg "Joe", the customer who has a newly placed order, from "Mary" customer who has none.
+    @Before
+    public void setUp() {
+        // given
+        simpleObject = fixtureScripts.runBuilderScript(SimpleObject_persona.FOO.builder());
+    }
 
+    @Test
+    public void accessible() {
+        // when
+        final String name = wrap(simpleObject).getName();
 
-=== Further approaches
+        // then
+        assertThat(name).isEqualTo(simpleObject.getName());
+    }
+    ...
+}
+----
 
-As of there are two other approaches.
+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".
 
-The first is to take advantage of a new `MultipleExecutionStrategy`, namely `EXECUTE_ONCE_BY_VALUE`.  Under this strategy the determination as to whether to run a given fixture script is by comparing the fixture script against all others that have run.
-If all fixture scripts implement value semantics, then they can effectively determine whether they need to run or not.
+Note though that the builder scripts (`BuilderScriptAbstract` implementations) are not only for use by enum personas.
+In a more complex entity there will be many potential values that need to be selected in order to create a valid instance.
+Rather than pushing this responsibility onto the caller, instead the builder script can automatically default some of these values.
 
-This strategy was introduced in order to better support the `ExcelFixture` fixture script (provided by the (non-ASF) link:http://platform.incode.org[Incode Platform^]'s excel module.
-The `ExcelFixture` takes an Excel spreadsheet and loads up each row.
-For those cases where we wish to ensure that the same spreadsheet is not loaded more than once, the `IGNORE` strategy would have required that a trivial subclass of `ExcelFixture` is created for each and every spreadsheet.
-The `EXECUTE_ONCE_BY_VALUE` on the other hand delegates the determination to the value semantics of the `ExcelFixture`, which is based on the contents of the spreadsheet.
+For example, for a customer's date of birth, this might default to a date making the customer an adult, aged between 18 and 65, say.
+For an email address or postal address, or an image, or some "lorem ipsum" text, the (non-ASF) link:http://platform.incode.org[Incode Platform^]'s fakedata module could for randomised values.
 
-[NOTE]
-====
-Note that as of `1.10.0` the `IGNORE` enum has been deprecated, replaced by `EXECUTE_ONCE_BY_CLASS`
-====
+The benefit of an intelligent builder is that it further simplifies the test.
+The developer reading the test then knows that everything that has been specified exactly is of significance.
 
-The second approach is in recognition that there is, in fact, something of a design flaw with the concept of `MultipleExecutionStrategy`: it requires that all fixture scripts being run follow the same conventions.
-There's a good argument that this shouldn't be a global "setting": the responsibility for determining whether a given fixture script should be executed should reside not in the `FixtureScripts` service but in the `FixtureScript` itself.
 
-Thus, the `FixtureScripts.ExecutionContext` exposes the `getPreviouslyExecuted()` method that allows the fixture script to check for itself which fixture scripts have already been run, and act accordingly.
-For this approach, the `MultipleExecutionStrategy` should be left as simply `EXECUTE`.
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_clock-fixtures.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_clock-fixtures.adoc
new file mode 100644
index 0000000..9ba5959
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_clock-fixtures.adoc
@@ -0,0 +1,28 @@
+[[_ugtst_fixture-scripts_clock-fixtures]]
+= Clock Fixtures (`1.16.0-SNAPSHOT`)
+: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 [...]
+:_basedir: ../../
+:_imagesdir: images/
+
+
+
+The `ClockFixture` is a pre-build fixture script that simply sets the time returned by the xref:../rgsvc/rgsvc.adoc#_rgsvc_api_ClockService[`ClockService`] to a known value.
+
+For example, to set the clock to return "3 Sept 2014", use:
+
+[source,java]
+----
+executionContext.executeChild(this, ClockFixture.setTo("2014-09-03"));
+----
+
+A variety of format strings are supported; the format "YYYY-MM-DD" (as shown above) will work in every locale.
+
+The fixture script requires that a `FixtureClock` is initialized.
+This happens automatically in any non-production environment, and in particular when running integration tests.
+
+
+The `TickingClockFixture` is another, slightly more sophisticated, fixture script.
+
+
+
+It requires that a TickingFixtureClock
\ No newline at end of file
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_sudo-service.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_sudo-service.adoc
index fbc9bdd..c9b746e 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_sudo-service.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_fixture-scripts_sudo-service.adoc
@@ -6,7 +6,8 @@
 
 
 
-Sometimes in our fixture scripts we want to perform a business action running as a particular user.  This might be for the usual reason - so that our fixtures accurately reflect the reality of the system with all business constraints enforced using the `WrapperFactory` - or more straightforwardly it might be simply that the action depends on the identity of the user invoking the action.
+Sometimes in our fixture scripts we want to perform a business action running as a particular user.
+This might be for the usual reason - so that our fixtures accurately reflect the reality of the system with all business constraints enforced using the `WrapperFactory` - or more straightforwardly it might be simply that the action depends on the identity of the user invoking the action.
 
 An example of the latter case is in the (non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp]'s `ToDoItem` class:
 
@@ -56,4 +57,5 @@ toDoItem = sudoService.sudo(username,
         });
 ----
 
-Behind the scenes the `SudoService` simply talks to the `DomainObjectContainer` to override the user returned by the `getUser()` API.  It is possible to override both users and roles.
+Behind the scenes the `SudoService` simply talks to the `DomainObjectContainer` to override the user returned by the `getUser()` API.
+It is possible to override both users and roles.
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prompt.png b/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prompt.png
index 6c22c49..5265855 100644
Binary files a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prompt.png and b/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prompt.png differ
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prototyping-menu.png b/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prototyping-menu.png
index ed85463..a4d71f6 100644
Binary files a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prototyping-menu.png and b/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/prototyping-menu.png differ
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list-specifying-number.png b/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list-specifying-number.png
deleted file mode 100644
index 2ac7e88..0000000
Binary files a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list-specifying-number.png and /dev/null differ
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list.png b/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list.png
index abe4a0e..902ee87 100644
Binary files a/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list.png and b/adocs/documentation/src/main/asciidoc/guides/ugtst/images/testing/fixture-scripts/result-list.png differ
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java
index 8a540d1..905f8ef 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java
@@ -36,7 +36,7 @@ public abstract class AppManifestAbstract implements AppManifest {
     private final List<Class<?>> modules;
     private final List<Class<?>> additionalServices;
     private final String authMechanism;
-    private final List<Class<? extends FixtureScript>> fixtures;
+    private final List<Class<? extends FixtureScript>> fixtureClasses;
     private final Map<String, String> configurationProperties;
 
     public AppManifestAbstract(final BuilderAbstract<?> builder) {
@@ -51,12 +51,12 @@ public abstract class AppManifestAbstract implements AppManifest {
         this.additionalServices = builderAdditionalServices;
 
         this.authMechanism = determineAuthMechanism(builder);
-        this.fixtures = determineFixtures(builder);
+        this.fixtureClasses = determineFixtures(builder);
 
         // note uses this.fixtures, so must come afterwards...
         this.configurationProperties = createConfigurationProperties(
                 builder.getAllPropertyResources(), builder.getAllIndividualConfigProps(),
-                this.fixtures);
+                this.fixtureClasses);
     }
 
     private String determineAuthMechanism(final ModuleOrBuilderAbstract<?> builder) {
@@ -159,7 +159,7 @@ public abstract class AppManifestAbstract implements AppManifest {
 
     @Override
     public final List<Class<? extends FixtureScript>> getFixtures() {
-        return fixtures;
+        return fixtureClasses;
     }
 
     /**
@@ -170,7 +170,7 @@ public abstract class AppManifestAbstract implements AppManifest {
      *     using {@link Builder#withFixtureScripts(Class[])} .
      * </p>
      */
-    protected void overrideFixtures(final List<Class<? extends FixtureScript>> fixtureScripts) {
+    protected void overrideFixtures(final List<Class<? extends FixtureScript>> fixtureScriptClasses) {
         // default implementation does nothing.
     }
 
diff --git a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java
index 364778d..5862db6 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/ClockFixture.java
@@ -26,44 +26,65 @@ import org.joda.time.format.DateTimeFormatter;
 import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.fixtures.FixtureClock;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
+import org.apache.isis.applib.fixturescripts.FixtureScriptWithExecutionStrategy;
+import org.apache.isis.applib.fixturescripts.FixtureScripts;
 
-public class ClockFixture extends FixtureScript {
+class ClockFixture extends FixtureScript implements FixtureScriptWithExecutionStrategy {
 
-    //region > factory methods, constructors
-    public static ClockFixture setTo(final String date) {
-        return new ClockFixture(date);
+    static ClockFixture setTo(final String date) {
+        return new ClockFixture().setDate(date);
     }
 
-    private LocalDateTime localDateTime;
-    private LocalDate localDate;
-
-    public ClockFixture() {
+    ClockFixture() {
         super(null, "clock");
     }
 
-    public ClockFixture(String dateStr) {
-        super(null, "clock");
-        if(!parse(dateStr)) {
-            throw new IllegalArgumentException(dateStr + " could not be parsed as a date/time or date");
-        }
+    private String date;
+
+    public String getDate() {
+        return date;
     }
-    //endregion
 
-    //region > parseAsLocalDateTime
-    private boolean parse(String dateStr) {
-        return dateStr == null ? true : parseNonNull(dateStr);
+    public ClockFixture setDate(final String date) {
+        this.date = date;
+        return this;
     }
 
-    private boolean parseNonNull(String dateStr) {
-        this.localDateTime = parseAsLocalDateTime(dateStr);
-        if(localDateTime == null) {
-            this.localDate = parseAsLocalDate(dateStr);
+    @Override
+    protected void execute(ExecutionContext ec) {
+
+        // can only be used in the context of integration tests
+        if (!(Clock.getInstance() instanceof FixtureClock)) {
+            throw new IllegalStateException("Clock has not been initialized as a FixtureClock");
+        }
+        final FixtureClock fixtureClock = (FixtureClock) FixtureClock.getInstance();
+
+        // check that some value has been set
+        checkParam("date", ec, String.class);
+
+        // process if can be parsed as a LocalDateTime
+        LocalDateTime ldt = parseAsLocalDateTime(date);
+        if (ldt != null) {
+            fixtureClock.setDate(ldt.getYear(), ldt.getMonthOfYear(), ldt.getDayOfMonth());
+            fixtureClock.setTime(ldt.getHourOfDay(), ldt.getMinuteOfHour());
+            return;
+        }
+
+        // else process if can be parsed as a LocalDate
+        LocalDate ld = parseAsLocalDate(date);
+        if (ld != null) {
+            fixtureClock.setDate(ld.getYear(), ld.getMonthOfYear(), ld.getDayOfMonth());
+            return;
         }
-        return this.localDateTime != null || this.localDate != null;
+
+        // else
+        throw new IllegalArgumentException(String.format(
+                "'%s' could not be parsed as a local date/time or local date", date));
     }
 
+    //region > parseAsLocalDateTime
     private static LocalDate parseAsLocalDate(String dateStr) {
-        for (DateTimeFormatter formatter : new DateTimeFormatter[]{
+        for (DateTimeFormatter formatter : new DateTimeFormatter[] {
                 DateTimeFormat.fullDateTime(),
                 DateTimeFormat.mediumDateTime(),
                 DateTimeFormat.shortDateTime(),
@@ -80,7 +101,7 @@ public class ClockFixture extends FixtureScript {
     }
 
     private static LocalDateTime parseAsLocalDateTime(String dateStr) {
-        for (DateTimeFormatter formatter : new DateTimeFormatter[]{
+        for (DateTimeFormatter formatter : new DateTimeFormatter[] {
                 DateTimeFormat.fullDateTime(),
                 DateTimeFormat.mediumDateTime(),
                 DateTimeFormat.shortDateTime(),
@@ -95,29 +116,10 @@ public class ClockFixture extends FixtureScript {
         }
         return null;
     }
-    //endregion
 
     @Override
-    protected void execute(ExecutionContext fixtureResults) {
-        if(!(Clock.getInstance() instanceof FixtureClock)) {
-            throw new IllegalStateException("Clock has not been initialized as a FixtureClock");
-        }
-        final FixtureClock fixtureClock = (FixtureClock) FixtureClock.getInstance();
-
-        if(localDateTime != null) {
-            fixtureClock.setDate(localDateTime.getYear(), localDateTime.getMonthOfYear(), localDateTime.getDayOfMonth());
-            fixtureClock.setTime(localDateTime.getHourOfDay(), localDateTime.getMinuteOfHour());
-            return;
-        }
-        if(localDate != null) {
-            fixtureClock.setDate(localDate.getYear(), localDate.getMonthOfYear(), localDate.getDayOfMonth());
-            return;
-        }
+    public FixtureScripts.MultipleExecutionStrategy getMultipleExecutionStrategy() {
+        return FixtureScripts.MultipleExecutionStrategy.EXECUTE;
     }
 
-    @Override
-    public String validateRun(String parameters) {
-        return parseAsLocalDateTime(parameters) == null && parseAsLocalDate(parameters) == null
-                ? "Parameter must be parseable as a date/time or as a date" : null;
-    }
 }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java
index 2440bf6..2e6e6f7 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/clock/TickingClockFixture.java
@@ -26,26 +26,42 @@ import org.apache.isis.applib.fixturescripts.FixtureScriptWithExecutionStrategy;
 import org.apache.isis.applib.fixturescripts.FixtureScripts;
 
 
-public class TickingClockFixture extends FixtureScript implements FixtureScriptWithExecutionStrategy {
+public class TickingClockFixture
+        extends FixtureScript
+        implements FixtureScriptWithExecutionStrategy {
+
+    //region > date property
+    private String date;
+    public String getDate() {
+        return date;
+    }
+    public TickingClockFixture setDate(final String date) {
+        this.date = date;
+        return this;
+    }
+    //endregion
 
     @Override
-    protected void execute(ExecutionContext executionContext) {
+    protected void execute(ExecutionContext ec) {
+
+        checkParam("date", ec, String.class);
 
         final Clock instance = Clock.getInstance();
 
         if(instance instanceof TickingFixtureClock) {
             TickingFixtureClock.reinstateExisting();
-            executionContext.executeChild(this, ClockFixture.setTo("2014-05-18"));
+            ec.executeChild(this, ClockFixture.setTo(date));
             TickingFixtureClock.replaceExisting();
         }
 
         if(instance instanceof FixtureClock) {
-            executionContext.executeChild(this, ClockFixture.setTo("2014-05-18"));
+            ec.executeChild(this, ClockFixture.setTo(date));
         }
     }
 
     @Override
     public FixtureScripts.MultipleExecutionStrategy getMultipleExecutionStrategy() {
-        return FixtureScripts.MultipleExecutionStrategy.EXECUTE_ONCE_BY_CLASS;
+        return FixtureScripts.MultipleExecutionStrategy.EXECUTE;
     }
+
 }
diff --git a/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifest.java b/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifest.java
index 69eaacc..96cdc75 100644
--- a/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifest.java
+++ b/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifest.java
@@ -27,16 +27,18 @@ import domainapp.application.DomainAppApplicationModule;
  */
 public class DomainAppAppManifest extends AppManifestAbstract2 {
 
-    public DomainAppAppManifest() {
-        super(Builder
-                .forModule(new DomainAppApplicationModule())
-                .withConfigurationPropertiesFile(DomainAppAppManifest.class,
+    public static final Builder BUILDER = Builder
+            .forModule(new DomainAppApplicationModule())
+            .withConfigurationPropertiesFile(DomainAppAppManifest.class,
                     "isis.properties",
                     "authentication_shiro.properties",
                     "persistor_datanucleus.properties",
                     "viewer_restfulobjects.properties",
                     "viewer_wicket.properties")
-                .withAuthMechanism("shiro"));
+            .withAuthMechanism("shiro");
+
+    public DomainAppAppManifest() {
+        super(BUILDER);
     }
 
 }
diff --git a/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifestWithFixtures.java b/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifestWithFixtures.java
index 062795e..f79d3ed 100644
--- a/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifestWithFixtures.java
+++ b/example/application/simpleapp/application/src/main/java/domainapp/application/manifest/DomainAppAppManifestWithFixtures.java
@@ -22,15 +22,16 @@ import java.util.List;
 
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 
-import domainapp.modules.simple.fixture.SimpleObjectBuilder;
+import domainapp.modules.simple.fixture.SimpleObject_persona;
 
 /**
  * Run the app but setting up any fixtures.
  */
 public class DomainAppAppManifestWithFixtures extends DomainAppAppManifest {
 
-    @Override protected void overrideFixtures(final List<Class<? extends FixtureScript>> fixtureScripts) {
-        fixtureScripts.add(SimpleObjectBuilder.class);
+    @Override
+    protected void overrideFixtures(final List<Class<? extends FixtureScript>> fixtureScripts) {
+        fixtureScripts.add(SimpleObject_persona.PersistAll.class);
     }
 
 }
diff --git a/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.layout.xml b/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.layout.xml
index f743828..6f6aa72 100644
--- a/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.layout.xml
+++ b/example/application/simpleapp/application/src/main/java/domainapp/application/services/homepage/HomePageViewModel.layout.xml
@@ -27,6 +27,7 @@
                     <action id="clearHints" hidden="EVERYWHERE"/>
                     <action id="downloadLayoutXml" hidden="EVERYWHERE"/>
                     <action id="rebuildMetamodel" hidden="EVERYWHERE"/>
+                    <action id="openRestApi" hidden="EVERYWHERE"/>
                 </bs3:col>
             </bs3:row>
         </bs3:col>
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModule.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModule.java
index e961c22..b1498a6 100644
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModule.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModule.java
@@ -29,13 +29,6 @@ import domainapp.modules.simple.fixture.SimpleObject_persona;
 public class SimpleModule extends ModuleAbstract {
 
     @Override
-    public FixtureScript getRefDataSetupFixture() {
-        // the intention of this method is to initialize ref data rather than operational/transactional data
-        // the line below demonstrates how to persist every instance of SimpleObject_persona enum easily
-        return new PersonaEnumPersistAll(SimpleObject_persona.class);
-    }
-
-    @Override
     public FixtureScript getTeardownFixture() {
         return new TeardownFixtureAbstract2() {
             @Override
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
index 6786d95..35506fa 100644
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
@@ -21,6 +21,7 @@ package domainapp.modules.simple.fixture;
 
 import org.apache.isis.applib.fixturescripts.PersonaWithBuilderScript;
 import org.apache.isis.applib.fixturescripts.PersonaWithFinder;
+import org.apache.isis.applib.fixturescripts.setup.PersonaEnumPersistAll;
 import org.apache.isis.applib.services.registry.ServiceRegistry2;
 
 import domainapp.modules.simple.dom.impl.SimpleObject;
@@ -54,4 +55,11 @@ public enum SimpleObject_persona implements PersonaWithBuilderScript<SimpleObjec
         SimpleObjectRepository simpleObjectRepository = serviceRegistry.lookupService(SimpleObjectRepository.class);
         return simpleObjectRepository.findByNameExact(name);
     }
+
+    public static class PersistAll
+            extends PersonaEnumPersistAll<SimpleObject_persona, SimpleObject, SimpleObjectBuilder> {
+        public PersistAll() {
+            super(SimpleObject_persona.class);
+        }
+    }
 }
diff --git a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java
index 8e8b030..04d3914 100644
--- a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java
+++ b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObjectMenu_IntegTest.java
@@ -30,32 +30,22 @@ import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.Test;
 
-import org.apache.isis.applib.fixturescripts.FixtureScript;
-import org.apache.isis.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.applib.fixturescripts.teardown.TeardownFixtureAbstract2;
-import org.apache.isis.applib.services.xactn.TransactionService;
-
-import domainapp.modules.simple.SimpleModule;
 import domainapp.modules.simple.dom.impl.SimpleObject;
 import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
-import domainapp.modules.simple.fixture.SimpleObjectBuilder;
 import domainapp.modules.simple.fixture.SimpleObject_persona;
 import domainapp.modules.simple.integtests.SimpleModuleIntegTestAbstract;
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class SimpleObjectMenu_IntegTest extends SimpleModuleIntegTestAbstract {
 
-    @Inject
-    FixtureScripts fixtureScripts;
-    @Inject
-    TransactionService transactionService;
-    @Inject
-    SimpleObjectMenu menu;
-
     public static class ListAll extends SimpleObjectMenu_IntegTest {
 
         @Test
-        public void happyCase() throws Exception {
+        public void happyCase() {
+
+            // given
+            fixtureScripts.runFixtureScript(new SimpleObject_persona.PersistAll());
+            transactionService.nextTransaction();
 
             // when
             final List<SimpleObject> all = wrap(menu).listAll();
@@ -65,17 +55,7 @@ public class SimpleObjectMenu_IntegTest extends SimpleModuleIntegTestAbstract {
         }
 
         @Test
-        public void whenNone() throws Exception {
-
-            // given
-            FixtureScript fs = new TeardownFixtureAbstract2() {
-                @Override
-                protected void execute(ExecutionContext executionContext) {
-                    deleteFrom(SimpleObject.class);
-                }
-            };
-            fixtureScripts.runFixtureScript(fs, null);
-            transactionService.nextTransaction();
+        public void whenNone() {
 
             // when
             final List<SimpleObject> all = wrap(menu).listAll();
@@ -88,19 +68,8 @@ public class SimpleObjectMenu_IntegTest extends SimpleModuleIntegTestAbstract {
     public static class Create extends SimpleObjectMenu_IntegTest {
 
         @Test
-        public void happyCase() throws Exception {
+        public void happyCase() {
 
-            // given
-            FixtureScript fs = new TeardownFixtureAbstract2() {
-                @Override
-                protected void execute(ExecutionContext executionContext) {
-                    deleteFrom(SimpleObject.class);
-                }
-            };
-            fixtureScripts.runFixtureScript(fs, null);
-            transactionService.nextTransaction();
-
-            // when
             wrap(menu).create("Faz");
 
             // then
@@ -109,25 +78,17 @@ public class SimpleObjectMenu_IntegTest extends SimpleModuleIntegTestAbstract {
         }
 
         @Test
-        public void whenAlreadyExists() throws Exception {
+        public void whenAlreadyExists() {
 
             // given
-            FixtureScript fs = new TeardownFixtureAbstract2() {
-                @Override
-                protected void execute(ExecutionContext executionContext) {
-                    deleteFrom(SimpleObject.class);
-                }
-            };
-            fixtureScripts.runFixtureScript(fs, null);
-            transactionService.nextTransaction();
-            wrap(menu).create("Faz");
+            fixtureScripts.runBuilderScript(SimpleObject_persona.FIZZ.builder());
             transactionService.nextTransaction();
 
             // then
             expectedExceptions.expectCause(causalChainContains(SQLIntegrityConstraintViolationException.class));
 
             // when
-            wrap(menu).create("Faz");
+            wrap(menu).create("Fizz");
             transactionService.nextTransaction();
         }
 
@@ -152,4 +113,7 @@ public class SimpleObjectMenu_IntegTest extends SimpleModuleIntegTestAbstract {
         }
     }
 
+    @Inject
+    SimpleObjectMenu menu;
+
 }
\ No newline at end of file
diff --git a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java
index a974686..75c10f9 100644
--- a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java
+++ b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/integtests/tests/SimpleObject_IntegTest.java
@@ -25,42 +25,31 @@ import javax.inject.Inject;
 import org.junit.Before;
 import org.junit.Test;
 
-import org.apache.isis.applib.fixturescripts.FixtureScripts;
 import org.apache.isis.applib.services.title.TitleService;
 import org.apache.isis.applib.services.wrapper.DisabledException;
 import org.apache.isis.applib.services.wrapper.InvalidException;
-import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.core.metamodel.services.jdosupport.Persistable_datanucleusIdLong;
 import org.apache.isis.core.metamodel.services.jdosupport.Persistable_datanucleusVersionTimestamp;
 
 import domainapp.modules.simple.dom.impl.SimpleObject;
-import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
 import domainapp.modules.simple.fixture.SimpleObject_persona;
 import domainapp.modules.simple.integtests.SimpleModuleIntegTestAbstract;
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
 
-    @Inject
-    FixtureScripts fixtureScripts;
-    @Inject
-    SimpleObjectMenu simpleObjectMenu;
-    @Inject
-    TransactionService transactionService;
-
     SimpleObject simpleObject;
 
     @Before
-    public void setUp() throws Exception {
-        simpleObject = SimpleObject_persona.FOO.findUsing(serviceRegistry);
-
-        assertThat(simpleObject).isNotNull();
+    public void setUp() {
+        // given
+        simpleObject = fixtureScripts.runBuilderScript(SimpleObject_persona.FOO.builder());
     }
 
     public static class Name extends SimpleObject_IntegTest {
 
         @Test
-        public void accessible() throws Exception {
+        public void accessible() {
             // when
             final String name = wrap(simpleObject).getName();
 
@@ -69,7 +58,7 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
         }
 
         @Test
-        public void not_editable() throws Exception {
+        public void not_editable() {
             // expect
             expectedExceptions.expect(DisabledException.class);
 
@@ -82,7 +71,7 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
     public static class UpdateName extends SimpleObject_IntegTest {
 
         @Test
-        public void can_be_updated_directly() throws Exception {
+        public void can_be_updated_directly() {
 
             // when
             wrap(simpleObject).updateName("new name");
@@ -93,7 +82,7 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
         }
 
         @Test
-        public void failsValidation() throws Exception {
+        public void failsValidation() {
 
             // expect
             expectedExceptions.expect(InvalidException.class);
@@ -111,7 +100,7 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
         TitleService titleService;
 
         @Test
-        public void interpolatesName() throws Exception {
+        public void interpolatesName() {
 
             // given
             final String name = wrap(simpleObject).getName();
@@ -127,7 +116,7 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
     public static class DataNucleusId extends SimpleObject_IntegTest {
 
         @Test
-        public void should_be_populated() throws Exception {
+        public void should_be_populated() {
             // when
             final Long id = mixin(Persistable_datanucleusIdLong.class, simpleObject).prop();
 
@@ -139,7 +128,7 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
     public static class DataNucleusVersionTimestamp extends SimpleObject_IntegTest {
 
         @Test
-        public void should_be_populated() throws Exception {
+        public void should_be_populated() {
             // when
             final Timestamp timestamp = mixin(Persistable_datanucleusVersionTimestamp.class, simpleObject).prop();
             // then
@@ -147,5 +136,4 @@ public class SimpleObject_IntegTest extends SimpleModuleIntegTestAbstract {
         }
     }
 
-
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.