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); + } + +}
