diff --git a/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java b/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java index 70ee731934..dd697eb863 100644 --- a/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java +++ b/src/test/java/jenkins/plugins/git/GitSampleRepoRule.java @@ -50,12 +50,14 @@ public final class GitSampleRepoRule extends AbstractSampleDVCSRepoRule { private static final Logger LOGGER = Logger.getLogger(GitSampleRepoRule.class.getName()); - protected void before() throws Throwable { + @Override + public void before() throws Throwable { super.before(); GitSCM.ALLOW_LOCAL_CHECKOUT = true; } - protected void after() { + @Override + public void after() { super.after(); GitSCM.ALLOW_LOCAL_CHECKOUT = false; } diff --git a/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtension.java b/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtension.java new file mode 100644 index 0000000000..8276c1c011 --- /dev/null +++ b/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtension.java @@ -0,0 +1,45 @@ +package jenkins.plugins.git.junit.jupiter; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; + +import jenkins.plugins.git.GitSampleRepoRule; + +/** + * A Junit5 extension to use {@link GitSampleRepoRule} with Junit5 + * See {@link WithGitSampleRepo} for details + */ +public class GitSampleRepoExtension implements ParameterResolver, AfterEachCallback { + + private static final String KEY = "git-sample-repo"; + private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace.create(GitSampleRepoExtension.class); + + @Override + public void afterEach(ExtensionContext context) { + var rule = context.getStore(NAMESPACE).remove(KEY, GitSampleRepoRule.class); + if (rule != null) { + rule.after(); + } + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return parameterContext.getParameter().getType().equals(GitSampleRepoRule.class); + } + + @Override + public GitSampleRepoRule resolveParameter(ParameterContext parameterContext, ExtensionContext context) { + var rule = context.getStore(NAMESPACE).getOrComputeIfAbsent(KEY, key -> new GitSampleRepoRule(), GitSampleRepoRule.class); + if (rule != null) { + try { + rule.before(); + } catch (Throwable t) { + throw new ParameterResolutionException(t.getMessage(), t); + } + } + return rule; + } +} diff --git a/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtensionClassTest.java b/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtensionClassTest.java new file mode 100644 index 0000000000..5f3bbe3a09 --- /dev/null +++ b/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtensionClassTest.java @@ -0,0 +1,20 @@ +package jenkins.plugins.git.junit.jupiter; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import jenkins.plugins.git.GitSampleRepoRule; + +@WithGitSampleRepo +class GitSampleRepoExtensionClassTest { + + @Test + void gitSampleRepoIsInjected(GitSampleRepoRule rule) throws Exception { + Assertions.assertNotNull(rule); + // somehow testing initialization + var root = rule.getRoot(); + Assertions.assertNotNull(root); + rule.init(); + Assertions.assertNotNull(rule.head()); + } +} diff --git a/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtensionMethodTest.java b/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtensionMethodTest.java new file mode 100644 index 0000000000..2cbded222b --- /dev/null +++ b/src/test/java/jenkins/plugins/git/junit/jupiter/GitSampleRepoExtensionMethodTest.java @@ -0,0 +1,20 @@ +package jenkins.plugins.git.junit.jupiter; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import jenkins.plugins.git.GitSampleRepoRule; + +class GitSampleRepoExtensionMethodTest { + + @WithGitSampleRepo + @Test + void gitSampleRepoIsInjected(GitSampleRepoRule rule) throws Exception { + Assertions.assertNotNull(rule); + // somehow testing initialization + var root = rule.getRoot(); + Assertions.assertNotNull(root); + rule.init(); + Assertions.assertNotNull(rule.head()); + } +} diff --git a/src/test/java/jenkins/plugins/git/junit/jupiter/WithGitSampleRepo.java b/src/test/java/jenkins/plugins/git/junit/jupiter/WithGitSampleRepo.java new file mode 100644 index 0000000000..a6c66bc280 --- /dev/null +++ b/src/test/java/jenkins/plugins/git/junit/jupiter/WithGitSampleRepo.java @@ -0,0 +1,62 @@ +package jenkins.plugins.git.junit.jupiter; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.extension.ExtendWith; + +import jenkins.plugins.git.GitSampleRepoRule; + +/** + * A meta annotation for the {@link GitSampleRepoExtension} to use {@link GitSampleRepoRule} with Junit5. + * Two possible usages: + *

+ * 1. Class annotation: each method of the class can have the rule injected as a parameter: + * + *

+ *
+ * @WithGitSampleRepo
+ * class ClassLevelAnnotationTest {
+ *
+ *     @Test
+ *     void usingRule(GitSampleRepoRule rule) {
+ *         // ...
+ *     }
+ *
+ *     @Test
+ *     void notUsingRule() {
+ *         // ...
+ *     }
+ * }
+ * 
+ *
+ *

+ * 2. Method annotation: only the annotated method can have the rule injected as a parameter: + * + *

+ *
+ * class MethodLevelAnnotationTest {
+ *
+ *     @WithGitSampleRepo
+ *     @Test
+ *     void usingRule(GitSampleRepoRule rule) {
+ *         // ...
+ *     }
+ *
+ *     @Test
+ *     void notUsingRule() {
+ *         // ...
+ *     }
+ * }
+ * 
+ *
+ */ +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@ExtendWith(GitSampleRepoExtension.class) +public @interface WithGitSampleRepo { +}