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

sseifert pushed a commit to branch feature/SLING-7803-junit5
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-sling-mock.git

commit 466b3aef33fafbe0bd260ca43d73da74542205fd
Author: sseifert <[email protected]>
AuthorDate: Mon Aug 6 17:23:13 2018 +0200

    SLING-7803 add junit5 extension
---
 junit5/pom.xml                                     |  43 +++++-
 .../testing/mock/sling/junit5/SlingContext.java    | 104 +++++++++++++
 .../mock/sling/junit5/SlingContextBuilder.java     | 161 +++++++++++++++++++++
 .../mock/sling/junit5/SlingContextCallback.java    |  33 +++++
 .../mock/sling/junit5/SlingContextExtension.java   | 129 +++++++++++++++++
 .../mock/sling/junit5/SlingContextStore.java       |  91 ++++++++++++
 .../testing/mock/sling/junit5/package-info.java    |  23 +++
 .../junit5/NoSlingModelsRegistrationTest.java      |  47 ++++++
 .../junit5/SlingContextMemberInstantiatedTest.java |  53 +++++++
 .../mock/sling/junit5/SlingContextMemberTest.java  |  52 +++++++
 .../mock/sling/junit5/SlingContextPluginTest.java  | 105 ++++++++++++++
 .../mock/sling/junit5/SlingContextTest.java        |  67 +++++++++
 12 files changed, 901 insertions(+), 7 deletions(-)

diff --git a/junit5/pom.xml b/junit5/pom.xml
index dd8930d..b3c1f9b 100644
--- a/junit5/pom.xml
+++ b/junit5/pom.xml
@@ -49,13 +49,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.testing.osgi-mock.junit5</artifactId>
-            <version>${osgi-mock.version}</version>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
@@ -66,8 +59,44 @@
             <scope>test</scope>
         </dependency>
 
+        <!-- JUnit 5 -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.vintage</groupId>
+            <artifactId>junit-vintage-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 
+    <dependencyManagement>
+        <dependencies>
+      
+            <dependency>
+                <groupId>org.junit</groupId>
+                <artifactId>junit-bom</artifactId>
+                <version>5.2.0</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+      
+        </dependencies>
+    </dependencyManagement>
+
     <build>
         <plugins>
 
diff --git 
a/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContext.java
 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContext.java
new file mode 100644
index 0000000..b8bbed4
--- /dev/null
+++ 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContext.java
@@ -0,0 +1,104 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import java.util.Map;
+
+import org.apache.sling.testing.mock.osgi.context.ContextPlugins;
+import org.apache.sling.testing.mock.sling.MockSling;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.context.SlingContextImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Sling Mock parameter object with resource resolver type defaulting to
+ * {@link ResourceResolverType#RESOURCERESOLVER_MOCK}.
+ * <p>
+ * Additionally you can subclass this class and provide further parameters via
+ * {@link SlingContextBuilder}.
+ * </p>
+ */
+@ConsumerType
+public final class SlingContext extends SlingContextImpl {
+
+    private final ContextPlugins plugins;
+    private boolean isSetUp;
+
+    /**
+     * Initialize Sling context.
+     */
+    public SlingContext() {
+      this(new ContextPlugins(), null, 
MockSling.DEFAULT_RESOURCERESOLVER_TYPE, true);
+    }
+
+    /**
+     * Initialize Sling context.
+     * @param resourceResolverType Resource resolver type.
+     */
+    public SlingContext(@NotNull final ResourceResolverType 
resourceResolverType) {
+        this(new ContextPlugins(), null, resourceResolverType, true);
+    }
+
+    /**
+     * Initialize Sling context.
+     * @param contextPlugins Context plugins
+     * @param resourceResolverFactoryActivatorProps Resource resolver factory
+     *            activator properties
+     * @param registerSlingModelsFromClassPath Automatic registering of all
+     *            Sling Models found in the classpath on startup.
+     * @param resourceResolverType Resource resolver type.
+     */
+    SlingContext(@NotNull final ContextPlugins contextPlugins,
+            @Nullable final Map<String, Object> 
resourceResolverFactoryActivatorProps,
+            @Nullable final ResourceResolverType resourceResolverType,
+            final boolean registerSlingModelsFromClassPath) {
+
+        this.plugins = contextPlugins;
+        
setResourceResolverFactoryActivatorProps(resourceResolverFactoryActivatorProps);
+        setRegisterSlingModelsFromClassPath(registerSlingModelsFromClassPath);
+        setResourceResolverType(resourceResolverType);
+    }
+
+    /**
+     * This is called by {@link SlingContextExtension} to set up context.
+     */
+    protected void setUpContext() {
+        isSetUp = true;
+        plugins.executeBeforeSetUpCallback(this);
+        super.setUp();
+    }
+
+    /**
+     * This is called by {@link SlingContextExtension} to tear down context.
+     */
+    protected void tearDownContext() {
+        super.tearDown();
+    }
+
+    ContextPlugins getContextPlugins() {
+        return plugins;
+    }
+
+    boolean isSetUp() {
+        return this.isSetUp;
+    }
+
+}
diff --git 
a/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextBuilder.java
 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextBuilder.java
new file mode 100644
index 0000000..428e086
--- /dev/null
+++ 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextBuilder.java
@@ -0,0 +1,161 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import java.util.Map;
+
+import org.apache.sling.testing.mock.osgi.context.ContextCallback;
+import org.apache.sling.testing.mock.osgi.context.ContextPlugin;
+import org.apache.sling.testing.mock.osgi.context.ContextPlugins;
+import org.apache.sling.testing.mock.osgi.context.OsgiContextImpl;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.jetbrains.annotations.NotNull;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Builder class for creating {@link SlingContext} instances with different 
sets
+ * of parameters.
+ */
+@ProviderType
+public final class SlingContextBuilder {
+
+    private final @NotNull ContextPlugins plugins = new ContextPlugins();
+    private ResourceResolverType resourceResolverType;
+    private Map<String, Object> resourceResolverFactoryActivatorProps;
+    private boolean registerSlingModelsFromClassPath = true;
+
+    /**
+     * Create builder with default resource resolver type.
+     */
+    public SlingContextBuilder() {
+        // use default resource resolver type
+    }
+
+    /**
+     * Create builder with given resource resolver type.
+     * @param resourceResolverType Resource resolver type.
+     */
+    public SlingContextBuilder(@NotNull ResourceResolverType 
resourceResolverType) {
+        this.resourceResolverType(resourceResolverType);
+    }
+
+    /**
+     * @param type Resource resolver type.
+     * @return this
+     */
+    public SlingContextBuilder resourceResolverType(@NotNull 
ResourceResolverType type) {
+        this.resourceResolverType = type;
+        return this;
+    }
+
+    /**
+     * @param <T> context type
+     * @param plugin Context plugin which listens to context lifecycle events.
+     * @return this
+     */
+    @SafeVarargs
+    public final <T extends OsgiContextImpl> SlingContextBuilder 
plugin(@NotNull ContextPlugin<T> @NotNull ... plugin) {
+        plugins.addPlugin(plugin);
+        return this;
+    }
+
+    /**
+     * @param <T> context type
+     * @param beforeSetUpCallback Allows the application to register an own
+     *            callback function that is called before the built-in setup
+     *            rules are executed.
+     * @return this
+     */
+    @SafeVarargs
+    public final <T extends OsgiContextImpl> SlingContextBuilder 
beforeSetUp(@NotNull ContextCallback<T> @NotNull ... beforeSetUpCallback) {
+        plugins.addBeforeSetUpCallback(beforeSetUpCallback);
+        return this;
+    }
+
+    /**
+     * @param <T> context type
+     * @param afterSetUpCallback Allows the application to register an own
+     *            callback function that is called after the built-in setup
+     *            rules are executed.
+     * @return this
+     */
+    @SafeVarargs
+    public final <T extends OsgiContextImpl> SlingContextBuilder 
afterSetUp(@NotNull ContextCallback<T> @NotNull ... afterSetUpCallback) {
+        plugins.addAfterSetUpCallback(afterSetUpCallback);
+        return this;
+    }
+
+    /**
+     * @param <T> context type
+     * @param beforeTearDownCallback Allows the application to register an own
+     *            callback function that is called before the built-in teardown
+     *            rules are executed.
+     * @return this
+     */
+    @SafeVarargs
+    public final <T extends OsgiContextImpl> SlingContextBuilder 
beforeTearDown(@NotNull ContextCallback<T> @NotNull ... beforeTearDownCallback) 
{
+        plugins.addBeforeTearDownCallback(beforeTearDownCallback);
+        return this;
+    }
+
+    /**
+     * @param <T> context type
+     * @param afterTearDownCallback Allows the application to register an own
+     *            callback function that is after before the built-in teardown
+     *            rules are executed.
+     * @return this
+     */
+    @SafeVarargs
+    public final <T extends OsgiContextImpl> SlingContextBuilder 
afterTearDown(@NotNull ContextCallback<T> @NotNull ... afterTearDownCallback) {
+        plugins.addAfterTearDownCallback(afterTearDownCallback);
+        return this;
+    }
+
+    /**
+     * Allows to override OSGi configuration parameters for the Resource
+     * Resolver Factory Activator service.
+     * @param props Configuration properties
+     * @return this
+     */
+    public SlingContextBuilder resourceResolverFactoryActivatorProps(@NotNull 
Map<String, Object> props) {
+        this.resourceResolverFactoryActivatorProps = props;
+        return this;
+    }
+
+    /**
+     * Automatic registering of all Sling Models found in the classpath on
+     * startup (active by default).
+     * @param value If set to false Sling Models are not registered
+     *            automatically from the classpath on startup.
+     * @return this
+     */
+    public SlingContextBuilder registerSlingModelsFromClassPath(boolean value) 
{
+        this.registerSlingModelsFromClassPath = value;
+        return this;
+    }
+
+    /**
+     * @return Build {@link SlingContext} instance.
+     */
+    public @NotNull SlingContext build() {
+        return new SlingContext(this.plugins, 
this.resourceResolverFactoryActivatorProps,
+                this.resourceResolverType, 
this.registerSlingModelsFromClassPath);
+    }
+
+}
diff --git 
a/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextCallback.java
 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextCallback.java
new file mode 100644
index 0000000..89285e1
--- /dev/null
+++ 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextCallback.java
@@ -0,0 +1,33 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import org.apache.sling.testing.mock.osgi.context.ContextCallback;
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Callback interface for application-specific setup and teardown operations to
+ * customize the {@link SlingContext} JUnit parameter context.
+ */
+@ConsumerType
+public interface SlingContextCallback extends ContextCallback<SlingContext> {
+
+    // specialized version of ContextCallback
+
+}
diff --git 
a/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextExtension.java
 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextExtension.java
new file mode 100644
index 0000000..c503058
--- /dev/null
+++ 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextExtension.java
@@ -0,0 +1,129 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.TestInstancePostProcessor;
+
+/**
+ * JUnit 5 extension that allows to inject {@link SlingContext} (or subclasses 
of
+ * it) parameters in test methods, and ensures that the context is set up and
+ * teared down properly for each test method.
+ */
+public final class SlingContextExtension implements ParameterResolver, 
TestInstancePostProcessor, BeforeEachCallback,
+        AfterEachCallback, AfterTestExecutionCallback {
+
+    /**
+     * Checks if test class has a {@link SlingContext} or derived field. If it 
has
+     * and is not instantiated, create an new {@link SlingContext} and store 
it in
+     * the field. If it is already instantiated reuse this instance and use it
+     * for all test methods.
+     */
+    @Override
+    public void postProcessTestInstance(Object testInstance, ExtensionContext 
extensionContext) throws Exception {
+        Field slingContextField = getFieldFromTestInstance(testInstance, 
SlingContext.class);
+        if (slingContextField != null) {
+            SlingContext context = (SlingContext) 
slingContextField.get(testInstance);
+            if (context != null) {
+                if (!context.isSetUp()) {
+                    context.setUpContext();
+                }
+                SlingContextStore.storeSlingContext(extensionContext, 
testInstance, context);
+            } else {
+                context = 
SlingContextStore.getOrCreateSlingContext(extensionContext, testInstance);
+                slingContextField.set(testInstance, context);
+            }
+        }
+    }
+
+    /**
+     * Support parameter injection for test methods of parameter type is 
derived
+     * from {@link SlingContext}.
+     */
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, 
ExtensionContext extensionContext) {
+        return 
SlingContext.class.isAssignableFrom(parameterContext.getParameter().getType());
+    }
+
+    /**
+     * Resolve (or create) {@link SlingContext} instance for test method
+     * parameter.
+     */
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, 
ExtensionContext extensionContext) {
+        return SlingContextStore.getOrCreateSlingContext(extensionContext, 
extensionContext.getRequiredTestInstance());
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext extensionContext) throws Exception 
{
+        applySlingContext(extensionContext, slingContext -> {
+            // call context plugins setup after all @BeforeEach methods were
+            // called
+            
slingContext.getContextPlugins().executeAfterSetUpCallback(slingContext);
+        });
+    }
+
+    @Override
+    public void afterTestExecution(ExtensionContext extensionContext) throws 
Exception {
+        applySlingContext(extensionContext, slingContext -> {
+            // call context plugins setup before any @AfterEach method is 
called
+            
slingContext.getContextPlugins().executeBeforeTearDownCallback(slingContext);
+        });
+    }
+
+    @Override
+    public void afterEach(ExtensionContext extensionContext) {
+        applySlingContext(extensionContext, slingContext -> {
+            // call context plugins setup after all @AfterEach methods were
+            // called
+            
slingContext.getContextPlugins().executeAfterTearDownCallback(slingContext);
+
+            // Tear down {@link SlingContext} after test is complete.
+            slingContext.tearDownContext();
+            SlingContextStore.removeSlingContext(extensionContext, 
extensionContext.getRequiredTestInstance());
+        });
+    }
+
+    private void applySlingContext(ExtensionContext extensionContext, 
Consumer<SlingContext> consumer) {
+        SlingContext slingContext = 
SlingContextStore.getSlingContext(extensionContext,
+                extensionContext.getRequiredTestInstance());
+        if (slingContext != null) {
+            consumer.accept(slingContext);
+        }
+    }
+
+    private Field getFieldFromTestInstance(Object testInstance, Class<?> type) 
{
+        Field contextField = 
Arrays.stream(testInstance.getClass().getDeclaredFields())
+                .filter(field -> 
type.isAssignableFrom(field.getType())).findFirst().orElse(null);
+        if (contextField != null) {
+            contextField.setAccessible(true);
+        }
+        return contextField;
+    }
+
+}
diff --git 
a/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextStore.java
 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextStore.java
new file mode 100644
index 0000000..dc391ab
--- /dev/null
+++ 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/SlingContextStore.java
@@ -0,0 +1,91 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+import org.junit.jupiter.api.extension.ExtensionContext.Store;
+
+/**
+ * Helper class managing storage of {@link SlingContext} in extension context 
store.
+ */
+final class SlingContextStore {
+
+    private static final Namespace Sling_CONTEXT_NAMESPACE = 
Namespace.create(SlingContextExtension.class);
+
+    private SlingContextStore() {
+        // static methods only
+    }
+
+    /**
+     * Get {@link SlingContext} from extension context store.
+     * @param extensionContext Extension context
+     * @param testInstance Test instance
+     * @return SlingContext or null
+     */
+    public static SlingContext getSlingContext(ExtensionContext 
extensionContext, Object testInstance) {
+        return getStore(extensionContext).get(testInstance, 
SlingContext.class);
+    }
+
+    /**
+     * Get {@link SlingContext} from extension context store - if it does not
+     * exist create a new one and store it.
+     * @param extensionContext Extension context
+     * @param testInstance Test instance
+     * @return SlingContext (never null)
+     */
+    public static SlingContext getOrCreateSlingContext(ExtensionContext 
extensionContext, Object testInstance) {
+        SlingContext context = getSlingContext(extensionContext, testInstance);
+        if (context == null) {
+            context = createSlingContext(extensionContext);
+            storeSlingContext(extensionContext, testInstance, context);
+        }
+        return context;
+    }
+
+    /**
+     * Removes {@link SlingContext} from extension context store (if it 
exists).
+     * @param extensionContext Extension context
+     * @param testInstance Test instance
+     */
+    public static void removeSlingContext(ExtensionContext extensionContext, 
Object testInstance) {
+        getStore(extensionContext).remove(testInstance);
+    }
+
+    /**
+     * Store {@link SlingContext} in extension context store.
+     * @param extensionContext Extension context
+     * @param testInstance Test instance
+     * @param slingContext Sling context
+     */
+    public static void storeSlingContext(ExtensionContext extensionContext, 
Object testInstance, SlingContext slingContext) {
+        getStore(extensionContext).put(testInstance, slingContext);
+    }
+
+    private static Store getStore(ExtensionContext context) {
+        return context.getStore(Sling_CONTEXT_NAMESPACE);
+    }
+
+    private static SlingContext createSlingContext(ExtensionContext 
extensionContext) {
+        SlingContext slingContext = new SlingContext();
+        slingContext.setUpContext();
+        return slingContext;
+    }
+
+}
diff --git 
a/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/package-info.java
 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/package-info.java
new file mode 100644
index 0000000..adc398a
--- /dev/null
+++ 
b/junit5/src/main/java/org/apache/sling/testing/mock/sling/junit5/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+/**
+ * JUnit 5 extensions for Sling context.
+ */
[email protected]("1.0.0")
+package org.apache.sling.testing.mock.sling.junit5;
diff --git 
a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/NoSlingModelsRegistrationTest.java
 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/NoSlingModelsRegistrationTest.java
new file mode 100644
index 0000000..873c350
--- /dev/null
+++ 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/NoSlingModelsRegistrationTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import static org.junit.Assert.assertNull;
+
+import 
org.apache.sling.testing.mock.sling.context.modelsautoreg.ClasspathRegisteredModel;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Test with {@link SlingContext} which uses by default
+ * {@link ResourceResolverMockSlingContext}.
+ */
+@ExtendWith(SlingContextExtension.class)
+class NoSlingModelsRegistrationTest {
+
+    private final SlingContext context = new SlingContextBuilder()
+            .registerSlingModelsFromClassPath(false)
+            .build();
+
+    @Test
+    public void testSlingModelClasspathRegistered() {
+        context.request().setAttribute("prop1", "myValue");
+        ClasspathRegisteredModel model = 
context.request().adaptTo(ClasspathRegisteredModel.class);
+        // expect null because ClasspathRegisteredModel should not be 
registered
+        // automatically from classpath
+        assertNull(model);
+    }
+
+}
diff --git 
a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberInstantiatedTest.java
 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberInstantiatedTest.java
new file mode 100644
index 0000000..d4a5dcc
--- /dev/null
+++ 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberInstantiatedTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Test with {@link SlingContext} as class member variable already 
instantiated.
+ */
+@ExtendWith(SlingContextExtension.class)
+@SuppressWarnings("null")
+class SlingContextMemberInstantiatedTest {
+
+    SlingContext context = new SlingContext(ResourceResolverType.JCR_MOCK);
+
+    @BeforeEach
+    void setUp() {
+        assertTrue(context.resourceResolver() instanceof ResourceResolverImpl);
+
+        context.create().resource("/content/test", "prop1", "value1");
+    }
+
+    @Test
+    void testResource() {
+        Resource resource = 
context.resourceResolver().getResource("/content/test");
+        assertEquals("value1", resource.getValueMap().get("prop1"));
+    }
+
+}
diff --git 
a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberTest.java
 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberTest.java
new file mode 100644
index 0000000..74231df
--- /dev/null
+++ 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.testing.resourceresolver.MockResourceResolver;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Test with {@link SlingContext} as class member variable.
+ */
+@ExtendWith(SlingContextExtension.class)
+@SuppressWarnings("null")
+class SlingContextMemberTest {
+
+    SlingContext context;
+
+    @BeforeEach
+    void setUp() {
+        assertTrue(context.resourceResolver() instanceof MockResourceResolver);
+
+        context.create().resource("/content/test", "prop1", "value1");
+    }
+
+    @Test
+    void testResource() {
+        Resource resource = 
context.resourceResolver().getResource("/content/test");
+        assertEquals("value1", resource.getValueMap().get("prop1"));
+    }
+
+}
diff --git 
a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextPluginTest.java
 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextPluginTest.java
new file mode 100644
index 0000000..be31245
--- /dev/null
+++ 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextPluginTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import 
org.apache.sling.testing.mock.sling.context.modelsautoreg.ClasspathRegisteredModel;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test with {@link SlingContext} with context plugins.
+ */
+@ExtendWith(SlingContextExtension.class)
+@SuppressWarnings("null")
+class SlingContextPluginTest {
+
+    private final SlingContextCallback contextBeforeSetup = 
mock(SlingContextCallback.class);
+    private final SlingContextCallback contextAfterSetup = 
mock(SlingContextCallback.class);
+    private final SlingContextCallback contextBeforeTeardown = 
mock(SlingContextCallback.class);
+    private final SlingContextCallback contextAfterTeardown = 
mock(SlingContextCallback.class);
+
+    private final SlingContext context = new SlingContextBuilder()
+            .beforeSetUp(contextBeforeSetup)
+            .afterSetUp(contextAfterSetup)
+            .beforeTearDown(contextBeforeTeardown)
+            .afterTearDown(contextAfterTeardown)
+            .resourceResolverFactoryActivatorProps(
+                    ImmutableMap.<String, Object> 
of("resource.resolver.searchpath", new String[] { "/apps", "/libs", 
"/testpath", }))
+            .build();
+
+    @BeforeEach
+    public void setUp() throws Exception {
+        verify(contextBeforeSetup).execute(context);
+    }
+
+    @Test
+    public void testRequest() throws Exception {
+        verify(contextAfterSetup).execute(context);
+        assertNotNull(context.request());
+    }
+
+    @Test
+    public void testResourceResolverFactoryActivatorProps() throws Exception {
+        verify(contextAfterSetup).execute(context);
+
+        // skip this test for resource resolver mock, because it does not
+        // respect the custom config
+        if (context.resourceResolverType() == 
ResourceResolverType.RESOURCERESOLVER_MOCK) {
+            return;
+        }
+
+        context.create().resource("/apps/node1");
+
+        context.create().resource("/libs/node1");
+        context.create().resource("/libs/node2");
+
+        context.create().resource("/testpath/node1");
+        context.create().resource("/testpath/node2");
+        context.create().resource("/testpath/node3");
+
+        assertEquals("/apps/node1", 
context.resourceResolver().getResource("node1").getPath());
+        assertEquals("/libs/node2", 
context.resourceResolver().getResource("node2").getPath());
+        assertEquals("/testpath/node3", 
context.resourceResolver().getResource("node3").getPath());
+        assertNull(context.resourceResolver().getResource("node4"));
+    }
+
+    @Test
+    public void testSlingModelClasspathRegistered() {
+        context.request().setAttribute("prop1", "myValue");
+        ClasspathRegisteredModel model = 
context.request().adaptTo(ClasspathRegisteredModel.class);
+        assertEquals("myValue", model.getProp1());
+    }
+
+    @AfterEach
+    public void tearDown() throws Exception {
+        verify(contextBeforeTeardown).execute(context);
+    }
+
+}
diff --git 
a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
new file mode 100644
index 0000000..fc956ab
--- /dev/null
+++ 
b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.sling.testing.mock.sling.junit5;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.sling.api.resource.Resource;
+import 
org.apache.sling.testing.mock.sling.context.modelsautoreg.ClasspathRegisteredModel;
+import org.apache.sling.testing.resourceresolver.MockResourceResolver;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Test with {@link SlingContext} as test method parameter.
+ */
+@ExtendWith(SlingContextExtension.class)
+@SuppressWarnings("null")
+class SlingContextTest {
+
+    @BeforeEach
+    void setUp(SlingContext context) {
+        assertTrue(context.resourceResolver() instanceof MockResourceResolver);
+
+        context.create().resource("/content/test", "prop1", "value1");
+    }
+
+    @Test
+    void testResource(SlingContext context) {
+        Resource resource = 
context.resourceResolver().getResource("/content/test");
+        assertEquals("value1", resource.getValueMap().get("prop1"));
+    }
+
+    @Test
+    public void testSlingModelClasspathRegistered(SlingContext context) {
+        context.request().setAttribute("prop1", "myValue");
+        ClasspathRegisteredModel model = 
context.request().adaptTo(ClasspathRegisteredModel.class);
+        assertEquals("myValue", model.getProp1());
+    }
+
+    @AfterEach
+    void tearDown(SlingContext context) throws Exception {
+        Resource resource = 
context.resourceResolver().getResource("/content/test");
+        assertEquals("value1", resource.getValueMap().get("prop1"));
+
+        context.resourceResolver().delete(resource);
+    }
+
+}

Reply via email to