diff --git a/platform/testFramework/core/intellij.platform.testFramework.core.iml b/platform/testFramework/core/intellij.platform.testFramework.core.iml
index 82fa42b4bcce..5a37e655679d 100644
--- a/platform/testFramework/core/intellij.platform.testFramework.core.iml
+++ b/platform/testFramework/core/intellij.platform.testFramework.core.iml
@@ -13,5 +13,6 @@
+
\ No newline at end of file
diff --git a/platform/testFramework/core/src/com/intellij/idea/Bombed.java b/platform/testFramework/core/src/com/intellij/idea/Bombed.java
index a1867e8f741c..1b29763aeba4 100644
--- a/platform/testFramework/core/src/com/intellij/idea/Bombed.java
+++ b/platform/testFramework/core/src/com/intellij/idea/Bombed.java
@@ -1,9 +1,9 @@
-/*
- * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
- */
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.idea;
+import com.intellij.idea.extensions.BombExplodedExtension;
import org.intellij.lang.annotations.JdkConstants;
+import org.junit.jupiter.api.extension.ExtendWith;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -12,6 +12,7 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
+@ExtendWith(BombExplodedExtension.class)
public @interface Bombed {
int year();
@JdkConstants.CalendarMonth int month();
diff --git a/platform/testFramework/core/src/com/intellij/idea/extensions/BombExplodedExtension.java b/platform/testFramework/core/src/com/intellij/idea/extensions/BombExplodedExtension.java
new file mode 100644
index 000000000000..79df8642df57
--- /dev/null
+++ b/platform/testFramework/core/src/com/intellij/idea/extensions/BombExplodedExtension.java
@@ -0,0 +1,39 @@
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.idea.extensions;
+
+import com.intellij.idea.Bombed;
+import com.intellij.testFramework.TestFrameworkUtil;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.extension.*;
+import org.junit.platform.commons.support.AnnotationSupport;
+
+public class BombExplodedExtension implements BeforeEachCallback, BeforeAllCallback, ExecutionCondition {
+ @Override
+ public void beforeEach(ExtensionContext context) {
+ explodeBomb(context);
+ }
+
+ @Override
+ public void beforeAll(ExtensionContext context) {
+ explodeBomb(context);
+ }
+
+ @Override
+ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
+ return AnnotationSupport.findAnnotation(context.getElement(), Bombed.class)
+ .map(bombed -> TestFrameworkUtil.bombExplodes(bombed)
+ ? ConditionEvaluationResult.enabled("Bomb exploded")
+ : ConditionEvaluationResult.disabled("Bomb not yet exploded"))
+ .orElse(ConditionEvaluationResult.enabled("No bomb defined"));
+ }
+
+ private static void explodeBomb(ExtensionContext context) {
+ AnnotationSupport.findAnnotation(context.getElement(), Bombed.class)
+ .ifPresent(bombed -> {
+ if (TestFrameworkUtil.bombExplodes(bombed)) {
+ String description = bombed.description().isEmpty() ? "" : " (" + bombed.description() + ")";
+ Assertions.fail("Bomb created by " + bombed.user() + description + " now explodes");
+ }
+ });
+ }
+}