diff --git a/base/tests/utils/integration/com/google/idea/blaze/base/run/producers/BlazeRunConfigurationProducerTestCase.java b/base/tests/utils/integration/com/google/idea/blaze/base/run/producers/BlazeRunConfigurationProducerTestCase.java index 906f5c1b60d..e32d459ef66 100644 --- a/base/tests/utils/integration/com/google/idea/blaze/base/run/producers/BlazeRunConfigurationProducerTestCase.java +++ b/base/tests/utils/integration/com/google/idea/blaze/base/run/producers/BlazeRunConfigurationProducerTestCase.java @@ -15,6 +15,7 @@ */ package com.google.idea.blaze.base.run.producers; +import com.google.common.collect.ImmutableList; import com.google.idea.blaze.base.BlazeIntegrationTestCase; import com.google.idea.blaze.base.EditorTestHelper; import com.google.idea.blaze.base.command.BlazeCommandName; @@ -93,6 +94,13 @@ protected static String getTestFilterContents(BlazeCommandRunConfiguration confi return handlerState != null ? handlerState.getTestFilterFlag() : null; } + @Nullable + protected static ImmutableList getTestArgsContents(BlazeCommandRunConfiguration config) { + BlazeCommandRunConfigurationCommonState handlerState = + config.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class); + return handlerState != null ? handlerState.getTestArgs() : null; + } + @Nullable protected static BlazeCommandName getCommandType(BlazeCommandRunConfiguration config) { BlazeCommandRunConfigurationCommonState handlerState = diff --git a/golang/src/com/google/idea/blaze/golang/run/producers/GoTestContextProvider.java b/golang/src/com/google/idea/blaze/golang/run/producers/GoTestContextProvider.java index 14f87ac6e34..6c149fd3c07 100644 --- a/golang/src/com/google/idea/blaze/golang/run/producers/GoTestContextProvider.java +++ b/golang/src/com/google/idea/blaze/golang/run/producers/GoTestContextProvider.java @@ -15,12 +15,17 @@ */ package com.google.idea.blaze.golang.run.producers; +import javax.annotation.Nullable; + import com.goide.execution.testing.GoTestFinder; import com.goide.execution.testing.GoTestRunConfigurationProducerBase; +import com.goide.execution.testing.frameworks.testify.GoTestifySupport; import com.goide.psi.GoFile; import com.goide.psi.GoFunctionOrMethodDeclaration; +import com.goide.psi.GoMethodDeclaration; import com.google.common.annotations.VisibleForTesting; import com.google.common.util.concurrent.ListenableFuture; +import com.google.idea.blaze.base.command.BlazeFlags; import com.google.idea.blaze.base.dependencies.TargetInfo; import com.google.idea.blaze.base.run.ExecutorType; import com.google.idea.blaze.base.run.TestTargetHeuristic; @@ -30,7 +35,6 @@ import com.intellij.execution.actions.ConfigurationContext; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import javax.annotation.Nullable; class GoTestContextProvider implements TestContextProvider { @@ -110,12 +114,20 @@ public RunConfigurationContext getTestContext(ConfigurationContext context) { .setDescription(file.getName()) .build(); } + String testFilterRegex = regexifyTestFilter(calculateRawTestFilterForElement(element, function)); - return TestContext.builder(/* sourceElement= */ function, ExecutorType.DEBUG_SUPPORTED_TYPES) + TestContext.Builder builder = TestContext.builder(/* sourceElement= */ function, + ExecutorType.DEBUG_SUPPORTED_TYPES) .addTestEnv(GO_TEST_WRAP_TESTV) .setTarget(target) - .setTestFilter(testFilterRegex) - .setDescription(String.format("%s#%s", file.getName(), function.getName())) - .build(); + .setDescription(String.format("%s#%s", file.getName(), function.getName())); + if (function instanceof GoMethodDeclaration method && + GoTestifySupport.getTestifySuiteTypeSpec(method) != null) { + builder.addBlazeFlagsModification(TestContext.BlazeFlagsModification.addFlagIfNotPresent( + BlazeFlags.TEST_ARG + "-testify.m=" + testFilterRegex)); + } else { + builder.setTestFilter(testFilterRegex); + } + return builder.build(); } } diff --git a/golang/tests/integrationtests/com/google/idea/blaze/golang/run/producers/BlazeGoTestConfigurationProducerTest.java b/golang/tests/integrationtests/com/google/idea/blaze/golang/run/producers/BlazeGoTestConfigurationProducerTest.java index 2defb33f1b8..f114069a92e 100644 --- a/golang/tests/integrationtests/com/google/idea/blaze/golang/run/producers/BlazeGoTestConfigurationProducerTest.java +++ b/golang/tests/integrationtests/com/google/idea/blaze/golang/run/producers/BlazeGoTestConfigurationProducerTest.java @@ -43,6 +43,8 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import java.util.List; +import java.util.Objects; + import org.jetbrains.annotations.NotNull; import org.junit.Before; import org.junit.Test; @@ -62,6 +64,7 @@ public final void init() { suppressNativeProducers(); setupMockTestingPackage(); + setupMockTestifyPackage(); } private void suppressNativeProducers() { @@ -89,6 +92,23 @@ private void setupMockTestingPackage() { packageFactory.put("testing", testingPkg); } + private void setupMockTestifyPackage() { + GoFile testifySrc = (GoFile)workspace.createPsiFile( + new WorkspacePath("github.com/stretchr/testify/suite/suite.go"), + "package suite", + "type Suite struct {}", + "func (suite *Suite) Run(name string, subtest func()) bool {}" + ); + GoPackage testifyPkg = new GoPackage(getProject(), "suite", + testifySrc.getContainingDirectory().getVirtualFile()) { + public @NotNull String getImportPath(boolean withVendoring) { + return "github.com/stretchr/testify/suite"; + } + }; + importResolver.put("github.com/stretchr/testify/suite", testifyPkg); + packageFactory.put("suite", testifyPkg); + } + private PsiFile setupWithSingleFile(String... contents) throws Throwable { PsiFile goFile = createAndIndexFile( @@ -137,6 +157,47 @@ public void testProducedFromGoFile() throws Throwable { assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST); } + @Test + public void testTestifyFile() throws Throwable { + PsiFile goFile = setupWithSingleFile( + """ + package foo + import "github.com/stretchr/testify/suite" + + type ExampleTestSuite struct { + suite.Suite + VariableThatShouldStartAtFive int + } + + func (suite *ExampleTestSuite) TestExample() { + } + + func TestExampleTestSuite(t *testing.T) { + suite.Run(t, new(ExampleTestSuite)) + } + """ + ); + + PsiElement element = getElementAtCaret(0, goFile); + String expectedTestFilter = "^TestExample$"; + ConfigurationContext context = createContextFromPsi(element); + List configurations = context.getConfigurationsFromContext(); + assertThat(configurations).isNotNull(); + assertThat(configurations).hasSize(1); + + ConfigurationFromContext fromContext = configurations.get(0); + assertThat(fromContext.isProducedBy(TestContextRunConfigurationProducer.class)).isTrue(); + assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class); + + BlazeCommandRunConfiguration config = + (BlazeCommandRunConfiguration)fromContext.getConfiguration(); + assertThat(config.getTargets()) + .containsExactly(TargetExpression.fromStringSafe("//foo/bar:foo_test")); + assertThat(Objects.requireNonNull(getTestArgsContents(config)).get(0)).isEqualTo( + "-testify.m=" + expectedTestFilter); + assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST); + } + @Test public void testProducedFromTestCase() throws Throwable { PsiFile goFile = setupWithSingleFile(