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:24 UTC

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

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>.