Skip to content

Commit cf03c4a

Browse files
authored
Allow tests in any marked test dir and optionally in sources (#5770)
* Allow tests in any marked test dir and optionally in sources * cleanup
1 parent bbf0b78 commit cf03c4a

File tree

6 files changed

+124
-22
lines changed

6 files changed

+124
-22
lines changed

src/io/flutter/FlutterBundle.properties

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,23 @@ settings.open.inspector.on.launch=Open Flutter Inspector view on app launch
209209
settings.hot.reload.on.save=Perform hot reload on save
210210
settings.enable.embedding.devtools=Enable embedding DevTools in the Flutter Inspector tool window
211211
settings.enable.bazel.hot.restart=Enable Bazel hot restart (refreshes generated files)
212+
settings.allow.tests.in.sources=<html>Allow files ending with <b>_test.dart</b> to be recognized as tests
213+
settings.allow.tests.tooltip=The directory must be marked as a sources root, such as <b>lib</b>.
214+
settings.font.packages=Font Packages
215+
settings.show.all.configs=Show all possible run configurations for apps or tests, even if a created configuration already exists
216+
settings.show.all.configs.tooltip=If there is a defined run configuration to watch a specific test and one to just run it, show both.
217+
settings.enable.embedding.devtools.tooltip=Use the web-based DevTools inspector in the Flutter Inspector tool window.
218+
settings.enable.androi.gradle.sync.tooltip=Provides advanced editing capabilities for Java and Kotlin code. Uses Gradle to find Android libraries then links them into the Flutter project.
219+
settings.experiments=Experiments
220+
settings.editor=Editor
221+
settings.show.build.guides=Show UI Guides for build methods
222+
settings.show.build.guides.tooltip=Visualize the widget tree structure from the outline view directly in build methods.
223+
settings.format.code.tooltip=On save, run dartfmt on changed Dart files.
224+
settings.organize.imports.tooltip=On save, organize imports for changed Dart files.
225+
settings.show.closing.labels=Show closing labels in Dart source code
226+
settings.sdk.copy.content=Copy to Clipboard
227+
settings.report.analytics.tooltip=Report anonymized usage information to Google Analytics.
228+
settings.enable.verbose.logging.tooltip=Enables verbose logging (this can be useful for diagnostic purposes).
212229

213230
action.new.project.title=New Flutter Project...
214231
welcome.new.project.title=Create New Flutter Project

src/io/flutter/FlutterUtils.java

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@
2424
import com.intellij.openapi.progress.ProcessCanceledException;
2525
import com.intellij.openapi.project.Project;
2626
import com.intellij.openapi.project.ProjectManager;
27-
import com.intellij.openapi.roots.ModuleRootManager;
28-
import com.intellij.openapi.roots.ModuleSourceOrderEntry;
29-
import com.intellij.openapi.roots.OrderEntry;
27+
import com.intellij.openapi.roots.*;
3028
import com.intellij.openapi.util.text.StringUtil;
3129
import com.intellij.openapi.vfs.LocalFileSystem;
30+
import com.intellij.openapi.vfs.VfsUtil;
3231
import com.intellij.openapi.vfs.VirtualFile;
3332
import com.intellij.psi.PsiElement;
3433
import com.intellij.psi.PsiFile;
@@ -38,6 +37,7 @@
3837
import com.jetbrains.lang.dart.psi.DartFile;
3938
import io.flutter.pub.PubRoot;
4039
import io.flutter.pub.PubRootCache;
40+
import io.flutter.settings.FlutterSettings;
4141
import io.flutter.utils.AndroidUtils;
4242
import io.flutter.utils.FlutterModuleUtils;
4343
import org.jetbrains.annotations.NotNull;
@@ -204,12 +204,48 @@ public static boolean isInTestDir(@Nullable DartFile file) {
204204

205205
// Check that we're in a project path that starts with 'test/'.
206206
final String relativePath = root.getRelativePath(file.getVirtualFile());
207-
if (relativePath == null || !(relativePath.startsWith("test/") || relativePath.startsWith("integration_test/"))) {
207+
if (relativePath == null) {
208208
return false;
209209
}
210+
final Module module = root.getModule(file.getProject());
211+
if (!(relativePath.startsWith("test/") || relativePath.startsWith("integration_test/"))) {
212+
if (!isInTestOrSourceRoot(module, file)) {
213+
return false;
214+
}
215+
}
210216

211217
// Check that we're in a Flutter module.
212-
return FlutterModuleUtils.isFlutterModule(root.getModule(file.getProject()));
218+
return FlutterModuleUtils.isFlutterModule(module);
219+
}
220+
221+
private static boolean isInTestOrSourceRoot(Module module, @NotNull DartFile file) {
222+
final ContentEntry[] entries = ModuleRootManager.getInstance(module).getContentEntries();
223+
final VirtualFile virtualFile = file.getContainingFile().getVirtualFile();
224+
boolean foundSourceRoot = false;
225+
for (ContentEntry entry : entries) {
226+
for (SourceFolder folder : entry.getSourceFolders()) {
227+
final VirtualFile folderFile = folder.getFile();
228+
if (folderFile == null) {
229+
continue;
230+
}
231+
if (folderFile.equals(VfsUtil.getCommonAncestor(folderFile, virtualFile))) {
232+
if (folder.getRootType().isForTests()) {
233+
return true; // Test file is in a directory marked as a test source root, but not named 'test'.
234+
}
235+
else {
236+
foundSourceRoot = true;
237+
break;
238+
}
239+
}
240+
}
241+
}
242+
if (foundSourceRoot) {
243+
// The file is in a sources root but not marked as tests.
244+
if (file.getName().endsWith(("_test.dart")) && FlutterSettings.getInstance().isAllowTestsInSourcesRoot()) {
245+
return true;
246+
}
247+
}
248+
return false;
213249
}
214250

215251
public static boolean isIntegrationTestingMode() {

src/io/flutter/sdk/FlutterSearchableOptionContributor.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
public class FlutterSearchableOptionContributor extends SearchableOptionContributor {
1717
@Override
1818
public void processOptions(@NotNull SearchableOptionProcessor processor) {
19+
// Keep these in the same order as FlutterBundle.properties
1920
add(processor, FlutterBundle.message("settings.try.out.features.still.under.development"));
2021
add(processor, FlutterBundle.message("settings.enable.android.gradle.sync"));
2122
// For some reason the word "report" is ignored by the search feature, but the other words work.
@@ -28,6 +29,24 @@ public void processOptions(@NotNull SearchableOptionProcessor processor) {
2829
add(processor, FlutterBundle.message("settings.open.inspector.on.launch"));
2930
add(processor, FlutterBundle.message("settings.hot.reload.on.save"));
3031
add(processor, FlutterBundle.message("settings.enable.embedding.devtools"));
32+
add(processor, FlutterBundle.message("settings.enable.bazel.hot.restart"));
33+
add(processor, FlutterBundle.message("settings.allow.tests.in.sources"));
34+
add(processor, FlutterBundle.message("settings.allow.tests.tooltip"));
35+
add(processor, FlutterBundle.message("settings.font.packages"));
36+
add(processor, FlutterBundle.message("settings.show.all.configs"));
37+
add(processor, FlutterBundle.message("settings.show.all.configs.tooltip"));
38+
add(processor, FlutterBundle.message("settings.enable.embedding.devtools.tooltip"));
39+
add(processor, FlutterBundle.message("settings.enable.androi.gradle.sync.tooltip"));
40+
add(processor, FlutterBundle.message("settings.experiments"));
41+
add(processor, FlutterBundle.message("settings.editor"));
42+
add(processor, FlutterBundle.message("settings.show.build.guides"));
43+
add(processor, FlutterBundle.message("settings.show.build.guides.tooltip"));
44+
add(processor, FlutterBundle.message("settings.format.code.tooltip"));
45+
add(processor, FlutterBundle.message("settings.organize.imports.tooltip"));
46+
add(processor, FlutterBundle.message("settings.show.closing.labels"));
47+
add(processor, FlutterBundle.message("settings.sdk.copy.content"));
48+
add(processor, FlutterBundle.message("settings.report.analytics.tooltip"));
49+
add(processor, FlutterBundle.message("settings.enable.verbose.logging.tooltip"));
3150
}
3251

3352
private static void add(@NotNull SearchableOptionProcessor processor, @NotNull String key) {

src/io/flutter/sdk/FlutterSettingsConfigurable.form

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="1" anchor="0" fill="0" indent="1" use-parent-layout="false"/>
5555
</constraints>
5656
<properties>
57-
<toolTipText value="Copy to Clipboard"/>
57+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.sdk.copy.content"/>
5858
</properties>
5959
</component>
6060
</children>
@@ -73,7 +73,7 @@
7373
</constraints>
7474
<properties>
7575
<text resource-bundle="io/flutter/FlutterBundle" key="settings.report.google.analytics"/>
76-
<toolTipText value="Report anonymized usage information to Google Analytics."/>
76+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.report.analytics.tooltip"/>
7777
</properties>
7878
</component>
7979
<component id="be19f" class="javax.swing.JCheckBox" binding="myEnableVerboseLoggingCheckBox" default-binding="true">
@@ -82,7 +82,7 @@
8282
</constraints>
8383
<properties>
8484
<text resource-bundle="io/flutter/FlutterBundle" key="settings.enable.verbose.logging"/>
85-
<toolTipText value="Enables verbose logging (this can be useful for diagnostic purposes)."/>
85+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.enable.verbose.logging.tooltip"/>
8686
</properties>
8787
</component>
8888
<component id="c59f0" class="com.intellij.ui.components.labels.LinkLabel" binding="myPrivacyPolicy">
@@ -92,8 +92,17 @@
9292
<properties>
9393
<horizontalAlignment value="2"/>
9494
<horizontalTextPosition value="2"/>
95-
<text value="www.google.com/policies/privacy"/>
96-
<toolTipText value="http://www.google.com/policies/privacy/"/>
95+
<text value="www.google.com/policies/privacy" noi18n="true"/>
96+
<toolTipText value="http://www.google.com/policies/privacy/" noi18n="true"/>
97+
</properties>
98+
</component>
99+
<component id="efbd7" class="javax.swing.JCheckBox" binding="myAllowTestsInSourcesRoot">
100+
<constraints>
101+
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
102+
</constraints>
103+
<properties>
104+
<text resource-bundle="io/flutter/FlutterBundle" key="settings.allow.tests.in.sources"/>
105+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.allow.tests.tooltip"/>
97106
</properties>
98107
</component>
99108
</children>
@@ -156,15 +165,15 @@
156165
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
157166
</constraints>
158167
<properties/>
159-
<border type="etched" title="Editor"/>
168+
<border type="etched" title-resource-bundle="io/flutter/FlutterBundle" title-key="settings.editor"/>
160169
<children>
161170
<component id="70775" class="javax.swing.JCheckBox" binding="myShowBuildMethodGuides">
162171
<constraints>
163172
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
164173
</constraints>
165174
<properties>
166-
<text value="Show UI Guides for build methods"/>
167-
<toolTipText value="Visualize the widget tree structure from the outline view directly in build methods."/>
175+
<text resource-bundle="io/flutter/FlutterBundle" key="settings.show.build.guides"/>
176+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.show.build.guides.tooltip"/>
168177
</properties>
169178
</component>
170179
<component id="a0dd8" class="javax.swing.JCheckBox" binding="myFormatCodeOnSaveCheckBox" default-binding="true">
@@ -173,7 +182,7 @@
173182
</constraints>
174183
<properties>
175184
<text resource-bundle="io/flutter/FlutterBundle" key="settings.format.code.on.save"/>
176-
<toolTipText value="On save, run dartfmt on changed Dart files."/>
185+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.format.code.tooltip"/>
177186
</properties>
178187
</component>
179188
<component id="8bd46" class="javax.swing.JCheckBox" binding="myOrganizeImportsOnSaveCheckBox" default-binding="true">
@@ -182,15 +191,15 @@
182191
</constraints>
183192
<properties>
184193
<text resource-bundle="io/flutter/FlutterBundle" key="settings.organize.imports.on.save"/>
185-
<toolTipText value="On save, organize imports for changed Dart files."/>
194+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.organize.imports.tooltip"/>
186195
</properties>
187196
</component>
188197
<component id="92f7c" class="javax.swing.JCheckBox" binding="myShowClosingLabels" default-binding="true">
189198
<constraints>
190199
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
191200
</constraints>
192201
<properties>
193-
<text value="Show closing labels in Dart source code"/>
202+
<text resource-bundle="io/flutter/FlutterBundle" key="settings.show.closing.labels"/>
194203
</properties>
195204
</component>
196205
</children>
@@ -201,7 +210,7 @@
201210
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
202211
</constraints>
203212
<properties/>
204-
<border type="etched" title="Experiments"/>
213+
<border type="etched" title-resource-bundle="io/flutter/FlutterBundle" title-key="settings.experiments"/>
205214
<children>
206215
<component id="42d6c" class="javax.swing.JLabel">
207216
<constraints>
@@ -217,7 +226,7 @@
217226
</constraints>
218227
<properties>
219228
<text resource-bundle="io/flutter/FlutterBundle" key="settings.enable.android.gradle.sync"/>
220-
<toolTipText value="Provides advanced editing capabilities for Java and Kotlin code. Uses Gradle to find Android libraries then links them into the Flutter project."/>
229+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.enable.androi.gradle.sync.tooltip"/>
221230
</properties>
222231
</component>
223232
<component id="33088" class="javax.swing.JCheckBox" binding="myEnableHotUiCheckBox">
@@ -235,16 +244,16 @@
235244
</constraints>
236245
<properties>
237246
<text resource-bundle="io/flutter/FlutterBundle" key="settings.enable.embedding.devtools"/>
238-
<toolTipText value="Use the web-based DevTools inspector in the Flutter Inspector tool window"/>
247+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.enable.embedding.devtools.tooltip"/>
239248
</properties>
240249
</component>
241250
<component id="e902c" class="javax.swing.JCheckBox" binding="myShowAllRunConfigurationsInContextCheckBox">
242251
<constraints>
243252
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
244253
</constraints>
245254
<properties>
246-
<text value="Show all possible run configurations for apps or tests, even if a created configuration already exists"/>
247-
<toolTipText value="If there is a defined run configuration to watch a specific test and one to just run it, show both."/>
255+
<text resource-bundle="io/flutter/FlutterBundle" key="settings.show.all.configs"/>
256+
<toolTipText resource-bundle="io/flutter/FlutterBundle" key="settings.show.all.configs.tooltip"/>
248257
</properties>
249258
</component>
250259
</children>
@@ -255,7 +264,7 @@
255264
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
256265
</constraints>
257266
<properties/>
258-
<border type="etched" title="Font Packages"/>
267+
<border type="etched" title-resource-bundle="io/flutter/FlutterBundle" title-key="settings.font.packages"/>
259268
<children>
260269
<scrollpane id="4e51e">
261270
<constraints>

src/io/flutter/sdk/FlutterSettingsConfigurable.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public class FlutterSettingsConfigurable implements SearchableConfigurable {
7777
private JCheckBox myShowClosingLabels;
7878
private FixedSizeButton myCopyButton;
7979
private JTextArea myFontPackagesTextArea; // This should be changed to a structured list some day.
80+
private JCheckBox myAllowTestsInSourcesRoot;
8081

8182
private final @NotNull Project myProject;
8283
private final WorkspaceCache workspaceCache;
@@ -235,6 +236,10 @@ public boolean isModified() {
235236
return true;
236237
}
237238

239+
if (settings.isAllowTestsInSourcesRoot() != myAllowTestsInSourcesRoot.isSelected()) {
240+
return true;
241+
}
242+
238243
if (!settings.getFontPackages().equals(myFontPackagesTextArea.getText())) {
239244
return true;
240245
}
@@ -290,6 +295,7 @@ public void apply() throws ConfigurationException {
290295
settings.setEnableHotUi(myEnableHotUiCheckBox.isSelected());
291296
settings.setEnableEmbeddedBrowsers(myEnableEmbeddedBrowsersCheckBox.isSelected());
292297
settings.setEnableBazelHotRestart(myEnableBazelHotRestartCheckBox.isSelected());
298+
settings.setAllowTestsInSourcesRoot(myAllowTestsInSourcesRoot.isSelected());
293299
settings.setShowAllRunConfigurationsInContext(myShowAllRunConfigurationsInContextCheckBox.isSelected());
294300
settings.setFontPackages(myFontPackagesTextArea.getText());
295301

@@ -336,6 +342,7 @@ public void reset() {
336342

337343
myEnableEmbeddedBrowsersCheckBox.setSelected(settings.isEnableEmbeddedBrowsers());
338344
myEnableBazelHotRestartCheckBox.setSelected(settings.isEnableBazelHotRestart());
345+
myAllowTestsInSourcesRoot.setSelected(settings.isAllowTestsInSourcesRoot());
339346

340347
myOrganizeImportsOnSaveCheckBox.setEnabled(myFormatCodeOnSaveCheckBox.isSelected());
341348
myIncludeAllStackTraces.setEnabled(myShowStructuredErrors.isSelected());

src/io/flutter/settings/FlutterSettings.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class FlutterSettings {
3636
private static final String enableBazelHotRestartKey = "io.flutter.editor.enableBazelHotRestart";
3737
private static final String showBazelHotRestartWarningKey = "io.flutter.showBazelHotRestartWarning";
3838
private static final String fontPackagesKey = "io.flutter.fontPackages";
39+
private static final String allowTestsInSourcesRootKey = "io.flutter.allowTestsInSources";
3940

4041
// TODO(helin24): This is to change the embedded browser setting back to true only once for Big Sur users. If we
4142
// switch to enabling the embedded browser for everyone, then delete this key.
@@ -141,6 +142,10 @@ public void sendSettingsToAnalytics(Analytics analytics) {
141142
analytics.sendEvent("settings", afterLastPeriod(changeBigSurToTrueKey));
142143
}
143144

145+
if (isAllowTestsInSourcesRoot()) {
146+
analytics.sendEvent("settings", afterLastPeriod(allowTestsInSourcesRootKey));
147+
}
148+
144149
if (!getFontPackages().isEmpty()) {
145150
analytics.sendEvent("settings", afterLastPeriod(fontPackagesKey));
146151
}
@@ -362,4 +367,13 @@ public void setChangeBigSurToTrue(boolean value) {
362367
getPropertiesComponent().setValue(changeBigSurToTrueKey, value, true);
363368
fireEvent();
364369
}
370+
371+
public boolean isAllowTestsInSourcesRoot() {
372+
return getPropertiesComponent().getBoolean(allowTestsInSourcesRootKey, false);
373+
}
374+
375+
public void setAllowTestsInSourcesRoot(boolean value) {
376+
getPropertiesComponent().setValue(allowTestsInSourcesRootKey, value, false);
377+
fireEvent();
378+
}
365379
}

0 commit comments

Comments
 (0)