diff --git a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerInitializer.java b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerInitializer.java index 79a64a59881..16cdb56447e 100644 --- a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerInitializer.java +++ b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerInitializer.java @@ -123,7 +123,7 @@ private static JUnitContainer getNewContainer(IPath containerPath, IClasspathAtt entriesList.add(BuildPathSupport.getHamcrestLibraryEntry()); break; case JUNIT5: - boolean vintage = isVintage(attributes); + boolean vintage = JUnitCore.isVintage(attributes); entriesList.add(BuildPathSupport.getJUnitJupiterApiLibraryEntry()); entriesList.add(BuildPathSupport.getJUnitJupiterEngineLibraryEntry()); entriesList.add(BuildPathSupport.getJUnitJupiterMigrationSupportLibraryEntry()); @@ -154,19 +154,6 @@ private static JUnitContainer getNewContainer(IPath containerPath, IClasspathAtt return new JUnitContainer(containerPath, entries); } - - private static boolean isVintage(IClasspathAttribute[] attributes) { - if (attributes != null) { - for (IClasspathAttribute attribute : attributes) { - if (JUnitCore.VINTAGE_ATTRIBUTE.equals(attribute.getName())) { - return Boolean.parseBoolean(attribute.getValue()); - } - } - } - // default is true for backward compat - return true; - } - private static boolean isValidJUnitContainerPath(IPath path) { return path != null && path.segmentCount() == 2 && JUnitCore.JUNIT_CONTAINER_ID.equals(path.segment(0)); } diff --git a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/junit/JUnitCore.java b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/junit/JUnitCore.java index 883111544aa..46f81f97d3e 100644 --- a/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/junit/JUnitCore.java +++ b/org.eclipse.jdt.junit.core/src/org/eclipse/jdt/junit/JUnitCore.java @@ -34,6 +34,7 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IType; @@ -234,4 +235,24 @@ public static ITestRunSession importTestRunSession(final String url, IProgressMo return null; } } + + /** + * @param attributes the attributes to check here, can be null + * @return true if vintage engine is enabled it false if not + * @since 3.13 + */ + public static boolean isVintage(IClasspathAttribute[] attributes) { + if (attributes != null) { + for (IClasspathAttribute attribute : attributes) { + if (JUnitCore.VINTAGE_ATTRIBUTE.equals(attribute.getName())) { + String value= attribute.getValue(); + if (value != null && !value.isBlank()) { + return Boolean.parseBoolean(value); + } + } + } + } + // default is true for backward compat + return true; + } } diff --git a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerWizardPage.java b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerWizardPage.java index b0928a0cc4f..d60aa45201b 100644 --- a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerWizardPage.java +++ b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/buildpath/JUnitContainerWizardPage.java @@ -16,11 +16,15 @@ import org.eclipse.jdt.junit.JUnitCore; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Text; import org.eclipse.core.runtime.IPath; @@ -31,6 +35,8 @@ import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jdt.core.IAccessRule; +import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; @@ -60,6 +66,8 @@ public class JUnitContainerWizardPage extends NewElementWizardPage implements IC private Combo fVersionCombo; private Text fResolvedPath; private Text fResolvedSourcePath; + private Button fVintage; + private Link fLink; public JUnitContainerWizardPage() { super("JUnitContainerPage"); //$NON-NLS-1$ @@ -119,9 +127,17 @@ public void createControl(Composite parent) { label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 1, 1)); label.setText(JUnitMessages.JUnitContainerWizardPage_combo_label); - fVersionCombo= new Combo(composite, SWT.READ_ONLY); + Composite comboComposite= new Composite(composite, SWT.NONE); + comboComposite.setLayout(new GridLayout(3, false)); + fVersionCombo= new Combo(comboComposite, SWT.READ_ONLY); fVersionCombo.setItems(JUnitMessages.JUnitContainerWizardPage_option_junit3, JUnitMessages.JUnitContainerWizardPage_option_junit4, JUnitMessages.JUnitContainerWizardPage_option_junit5); - fVersionCombo.setFont(composite.getFont()); + fVersionCombo.setFont(comboComposite.getFont()); + fVintage = new Button(comboComposite, SWT.CHECK); + fLink= new Link(comboComposite, SWT.NONE); + fLink.setText(JUnitMessages.JUnitContainerWizardPage_enableVintage); + fLink.setToolTipText(JUnitMessages.JUnitContainerWizardPage_enableVintage_tooltip); + fVintage.setToolTipText(JUnitMessages.JUnitContainerWizardPage_enableVintage_tooltip); + fLink.addSelectionListener(SelectionListener.widgetSelectedAdapter(e->Program.launch("https://junit.org/junit5/docs/current/user-guide/#overview-what-is-junit-5"))); //$NON-NLS-1$ GridData data= new GridData(GridData.BEGINNING, GridData.CENTER, false, false, 1, 1); data.widthHint= converter.convertWidthInCharsToPixels(15); @@ -133,8 +149,10 @@ public void createControl(Composite parent) { fVersionCombo.select(1); } else { fVersionCombo.select(2); + fVintage.setSelection(fContainerEntryResult!=null && JUnitCore.isVintage(fContainerEntryResult.getExtraAttributes())); } fVersionCombo.addModifyListener(e -> doSelectionChanged()); + fVintage.addSelectionListener(SelectionListener.widgetSelectedAdapter(e->doSelectionChanged())); label= new Label(composite, SWT.NONE); label.setFont(composite.getFont()); @@ -178,17 +196,27 @@ protected void doSelectionChanged() { IClasspathEntry libEntry; IPath containerPath; + IClasspathAttribute[] extraAttributes; if (fVersionCombo != null && fVersionCombo.getSelectionIndex() == 2) { containerPath= JUnitCore.JUNIT5_CONTAINER_PATH; libEntry= BuildPathSupport.getJUnitJupiterApiLibraryEntry(); + fVintage.setVisible(true); + fLink.setVisible(true); + extraAttributes= new IClasspathAttribute[] {JavaCore.newClasspathAttribute(JUnitCore.VINTAGE_ATTRIBUTE, Boolean.toString(fVintage.getSelection()))}; } else if (fVersionCombo != null && fVersionCombo.getSelectionIndex() == 1) { containerPath= JUnitCore.JUNIT4_CONTAINER_PATH; libEntry= BuildPathSupport.getJUnit4LibraryEntry(); + fVintage.setVisible(false); + fLink.setVisible(false); + extraAttributes= new IClasspathAttribute[0]; } else { containerPath= JUnitCore.JUNIT3_CONTAINER_PATH; libEntry= BuildPathSupport.getJUnit3LibraryEntry(); if (libEntry == null) libEntry= BuildPathSupport.getJUnit4as3LibraryEntry(); // JUnit 4 includes most of JUnit 3, so let's cheat + fVintage.setVisible(false); + fLink.setVisible(false); + extraAttributes= new IClasspathAttribute[0]; } if (libEntry == null) { @@ -202,7 +230,8 @@ protected void doSelectionChanged() { status.setWarning(JUnitMessages.JUnitContainerWizardPage_warning_java8_required); } } - fContainerEntryResult= JavaCore.newContainerEntry(containerPath); + fContainerEntryResult= JavaCore.newContainerEntry(containerPath, new IAccessRule[0],extraAttributes, + false); if (fResolvedPath != null && !fResolvedPath.isDisposed()) { if (libEntry != null) { diff --git a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.java b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.java index ea93b2809d1..855aab6167c 100644 --- a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.java +++ b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.java @@ -90,6 +90,10 @@ public final class JUnitMessages extends NLS { public static String JUnitContainerWizardPage_option_junit5; + public static String JUnitContainerWizardPage_enableVintage; + + public static String JUnitContainerWizardPage_enableVintage_tooltip; + public static String JUnitClasspathFixProcessor_progress_desc; public static String JUnitContainerWizardPage_resolved_label; diff --git a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.properties b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.properties index ef49bee3bc5..08fe52dc7a2 100644 --- a/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.properties +++ b/org.eclipse.jdt.junit/src/org/eclipse/jdt/internal/junit/ui/JUnitMessages.properties @@ -190,6 +190,8 @@ JUnitContainerWizardPage_wizard_title=JUnit Library JUnitContainerWizardPage_option_junit3=JUnit 3 JUnitContainerWizardPage_option_junit4=JUnit 4 JUnitContainerWizardPage_option_junit5=JUnit 5 +JUnitContainerWizardPage_enableVintage=Enable JUnit 3/4 Support +JUnitContainerWizardPage_enableVintage_tooltip=Enable the JUnit Vintage TestEngine for running JUnit 3 and JUnit 4 based tests on the JUnit Platform. JUnitContainerWizardPage_resolved_label=Current location: JUnitLaunchShortcut_message_launchfailed=Launching of JUnit tests unexpectedly failed. Check log for details. JUnitLaunchConfigurationTab_error_noContainer=No project, source folder or package is specified