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 2013/07/12 15:09:03 UTC
git commit: ISIS-463: new IntegrationTestAbstract;
added convenience mehods.
Updated Branches:
refs/heads/master 33c61d43b -> 593f500bc
ISIS-463: new IntegrationTestAbstract; added convenience mehods.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/593f500b
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/593f500b
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/593f500b
Branch: refs/heads/master
Commit: 593f500bcde5a4083a2d664968a29b796873b791
Parents: 33c61d4
Author: Dan Haywood <da...@apache.org>
Authored: Fri Jul 12 13:59:14 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Jul 12 13:59:14 2013 +0100
----------------------------------------------------------------------
.../IntegrationTestAbstract.java | 148 +++++++++++++++++++
.../integtestsupport/IsisSystemForTest.java | 22 ++-
.../ScenarioExecutionForIntegration.java | 11 +-
.../specsupport/specs/CukeStepDefsAbstract.java | 135 ++++++++++++++++-
4 files changed, 304 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/593f500b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract.java
----------------------------------------------------------------------
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract.java
new file mode 100644
index 0000000..e4f9d55
--- /dev/null
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.core.integtestsupport;
+
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.MethodRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.core.specsupport.scenarios.ScenarioExecution;
+import org.apache.isis.core.specsupport.specs.CukeStepDefsAbstract;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+
+/**
+ * Base class for integration tests.
+ *
+ * <p>
+ * There is substantial overlap with {@link CukeStepDefsAbstract}, and it would be
+ * possible to combine. However, the code is quite simple; chosen not to in order
+ * to make it easier to see the equivalence of these two classes.
+ *
+ */
+public abstract class IntegrationTestAbstract {
+
+ protected static ScenarioExecution scenarioExecution;
+
+ // //////////////////////////////////////
+
+
+ /**
+ * Convenience method
+ */
+ public void put(String type, String id, Object value) {
+ scenarioExecution().put(type, id, value);
+ }
+
+ /**
+ * Convenience method
+ */
+ public Object get(String type, String id) {
+ return scenarioExecution().get(type, id);
+ }
+
+ /**
+ * Convenience method
+ */
+ public <X> X get(String type, String id, Class<X> cls) {
+ return scenarioExecution().get(type, id ,cls);
+ }
+
+ /**
+ * Convenience method
+ */
+ protected <T> T service(Class<T> cls) {
+ return scenarioExecution().service(cls);
+ }
+
+ /**
+ * Convenience method
+ */
+ protected DomainObjectContainer container() {
+ return scenarioExecution().container();
+ }
+
+ /**
+ * Convenience method
+ */
+ protected WrapperFactory wrapperFactory() {
+ return scenarioExecution().wrapperFactory();
+ }
+
+ /**
+ * Convenience method
+ */
+ protected <T> T wrap(T obj) {
+ return scenarioExecution().wrapperFactory().wrap(obj);
+ }
+
+ /**
+ * Convenience method
+ */
+ protected <T> T unwrap(T obj) {
+ return scenarioExecution().wrapperFactory().unwrap(obj);
+ }
+
+
+ private ScenarioExecution scenarioExecution() {
+ return scenarioExecution;
+ }
+
+ // //////////////////////////////////////
+
+ /**
+ * The order is important; this rule is outermost, and must - at a minimum - come before
+ * the {@link #expectedExceptions} rule.
+ */
+ @Rule
+ public IsisTransactionRule isisTransactionRule = new IsisTransactionRule();
+
+ private static class IsisTransactionRule implements MethodRule {
+
+ @Override
+ public Statement apply(final Statement base, final FrameworkMethod method, final Object target) {
+ final IsisSystemForTest isft = IsisSystemForTest.get();
+
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ isft.beginTran();
+ try {
+ base.evaluate();
+ isft.commitTran();
+ } catch(Throwable e) {
+ isft.bounceSystem();
+ throw e;
+ }
+ }
+ };
+ }
+ }
+
+ @Rule
+ public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+ @Rule
+ public ExpectedException expectedExceptions = ExpectedException.none();
+}
+
http://git-wip-us.apache.org/repos/asf/isis/blob/593f500b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
----------------------------------------------------------------------
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
index 9f4f6d8..f054cce 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
@@ -117,7 +117,27 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
}
+ // //////////////////////////////////////
+ private static ThreadLocal<IsisSystemForTest> ISFT = new ThreadLocal<IsisSystemForTest>();
+
+ public static IsisSystemForTest getElseNull() {
+ return ISFT.get();
+ }
+
+ public static IsisSystemForTest get() {
+ final IsisSystemForTest isft = ISFT.get();
+ if(isft == null) {
+ throw new IllegalStateException("No IsisSystemForTest available on thread; call #set(IsisSystemForTest) first");
+ }
+ return isft;
+ }
+
+ public static void set(IsisSystemForTest isft) {
+ ISFT.set(isft);
+ }
+
+ // //////////////////////////////////////
private IsisSystemDefault isisSystem;
@@ -673,6 +693,4 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
}
-
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/593f500b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java
----------------------------------------------------------------------
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java
index dfc9653..7a8efde 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java
@@ -18,6 +18,7 @@ package org.apache.isis.core.integtestsupport.scenarios;
import org.apache.isis.applib.fixtures.InstallableFixture;
import org.apache.isis.core.integtestsupport.IsisSystemForTest;
+import org.apache.isis.core.specsupport.scenarios.DomainServiceProvider;
import org.apache.isis.core.specsupport.scenarios.ScenarioExecution;
@@ -33,11 +34,11 @@ import org.apache.isis.core.specsupport.scenarios.ScenarioExecution;
*/
public class ScenarioExecutionForIntegration extends ScenarioExecution {
- protected final IsisSystemForTest isft;
-
- public ScenarioExecutionForIntegration(IsisSystemForTest isft) {
- super(isft);
- this.isft = isft;
+ private IsisSystemForTest isft;
+
+ public ScenarioExecutionForIntegration() {
+ super(IsisSystemForTest.get());
+ this.isft = (IsisSystemForTest) dsp;
}
http://git-wip-us.apache.org/repos/asf/isis/blob/593f500b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeStepDefsAbstract.java
----------------------------------------------------------------------
diff --git a/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeStepDefsAbstract.java b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeStepDefsAbstract.java
index 1fbad8d..190a39e 100644
--- a/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeStepDefsAbstract.java
+++ b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeStepDefsAbstract.java
@@ -16,6 +16,17 @@
*/
package org.apache.isis.core.specsupport.specs;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.junit.Assert;
+
import cucumber.api.java.Before;
import org.apache.isis.applib.DomainObjectContainer;
@@ -23,8 +34,9 @@ import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.core.specsupport.scenarios.ScenarioExecution;
import org.apache.isis.core.specsupport.scenarios.ScenarioExecutionScope;
+
/**
- * Base class for unit-scope Cucumber step definitions.
+ * Base class for Cucumber-JVM step definitions.
*
* <p>
* Simply declares that an instance of {@link ScenarioExecution} (or a subclass)
@@ -46,28 +58,141 @@ public abstract class CukeStepDefsAbstract {
}
return scenarioExecution;
}
+
+ // //////////////////////////////////////
+
+ /**
+ * Convenience method
+ */
+ public void put(String type, String id, Object value) {
+ scenarioExecution().put(type, id, value);
+ }
/**
- * Convenience
+ * Convenience method
+ */
+ public Object get(String type, String id) {
+ return scenarioExecution().get(type, id);
+ }
+
+ /**
+ * Convenience method
+ */
+ public <X> X get(String type, String id, Class<X> cls) {
+ return scenarioExecution().get(type, id ,cls);
+ }
+
+ /**
+ * Convenience method
*/
protected <T> T service(Class<T> cls) {
return scenarioExecution().service(cls);
}
/**
- * Convenience
+ * Convenience method
*/
protected DomainObjectContainer container() {
return scenarioExecution().container();
}
/**
- * Convenience
+ * Convenience method
*/
protected WrapperFactory wrapperFactory() {
return scenarioExecution().wrapperFactory();
}
+ /**
+ * Convenience method
+ */
+ protected <T> T wrap(T obj) {
+ return scenarioExecution.wrapperFactory().wrap(obj);
+ }
+
+ /**
+ * Convenience method
+ */
+ protected <T> T unwrap(T obj) {
+ return scenarioExecution.wrapperFactory().unwrap(obj);
+ }
+
+ // //////////////////////////////////////
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static void assertTableEquals(final List listOfExpecteds, final Iterable iterableOfActuals) {
+ final List<Object> listOfActuals = Lists.newArrayList(iterableOfActuals);
+ assertThat(listOfActuals.size(), is(listOfExpecteds.size()));
+
+ for (int i=0; i<listOfActuals.size(); i++) {
+
+ final Object actual = listOfActuals.get(i);
+ final Object expected = listOfExpecteds.get(i);
+
+ final Field[] expectedFields = expected.getClass().getDeclaredFields();
+ for (Field field : expectedFields) {
+ final String propertyName = field.getName();
+ final Object actualProp = getProperty(actual, propertyName );
+ final Object expectedProp = getProperty(expected, propertyName);
+
+ assertThat("Values differ for property: " + propertyName, actualProp, is(expectedProp));
+ }
+ }
+ }
+
+
+ private static Object getProperty(Object obj, String propertyName) {
+ if(obj == null) {
+ return null;
+ }
+ final Class<? extends Object> cls = obj.getClass();
+ try {
+ final String methodName = "get" + capitalize(propertyName);
+ final Method method = cls.getMethod(methodName, new Class[]{});
+ if(method != null) {
+ return method.invoke(obj);
+ }
+ } catch (Exception e) {
+ // continue
+ }
+
+ try {
+ final String methodName = "is" + capitalize(propertyName);
+ final Method method = cls.getMethod(methodName, new Class[]{});
+ if(method != null) {
+ return method.invoke(obj);
+ }
+ } catch (Exception e) {
+ // continue
+ }
+
+ try {
+ final Field field = cls.getDeclaredField(propertyName);
+ if(field != null) {
+ if(!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+ return field.get(obj);
+ }
+ } catch (Exception e) {
+ // continue
+ }
+
+ Assert.fail("Unable to locate property '" + propertyName + "' in object " + obj);
+ return null;
+ }
+
+ private static String capitalize(final String str) {
+ if (str == null || str.length() == 0) {
+ return str;
+ }
+ if (str.length() == 1) {
+ return str.toUpperCase();
+ }
+ return Character.toUpperCase(str.charAt(0)) + str.substring(1);
+ }
+
+
// //////////////////////////////////////
/**
@@ -94,7 +219,7 @@ public abstract class CukeStepDefsAbstract {
* }
* @cucumber.api.java.Before("@integration")
* public void beforeScenarioIntegrationScope() {
- * before(new ScenarioExecutionScope(ScenarioExecutionForMyAppIntegration.class));
+ * before(ScenarioExecutionScope.INTEGRATION);
* }
* </pre>
* where <tt>ScenarioExecutionForMyAppIntegration</tt> is an application-specific subclass of