# This patch file was generated by NetBeans IDE # Following Index: paths are relative to: /home/theofanis/repositories/core-main # This patch can be applied using context Tools: Patch action on respective folder. # It uses platform neutral UTF-8 encoding and \n newlines. # Above lines and this line are ignored by the patching process. Index: apisupport.ant/src/org/netbeans/modules/apisupport/project/ui/ModuleActions.java --- apisupport.ant/src/org/netbeans/modules/apisupport/project/ui/ModuleActions.java +++ apisupport.ant/src/org/netbeans/modules/apisupport/project/ui/ModuleActions.java @@ -202,7 +202,7 @@ } else if (command.equals(COMMAND_TEST)) { return project.supportedTestTypes().contains("unit"); } else if (command.equals(COMMAND_TEST_SINGLE)) { - return findTestSourcesForSources(context) != null || findTestSources(context, true) != null; + return findTestSourcesForSources(context) != null || findTestSources(context, true) != null || findTestSourcesForFiles(context) != null; } else if (command.equals(COMMAND_DEBUG_TEST_SINGLE)) { TestSources testSources = findTestSourcesForSources(context); if (testSources == null) @@ -247,9 +247,13 @@ private static final String SUBSTNG = "NGTest.java"; // NOI18N private FileObject[] findSources(Lookup context) { + return findSources(context, false, true); + } + + private FileObject[] findSources(Lookup context, boolean findInPackages, boolean strict) { FileObject srcDir = project.getSourceDirectory(); if (srcDir != null) { - FileObject[] files = ActionUtils.findSelectedFiles(context, srcDir, ".java", true); // NOI18N + FileObject[] files = ActionUtils.findSelectedFiles(context, srcDir, findInPackages ? null : ".java", strict); // NOI18N //System.err.println("findSources: srcDir=" + srcDir + " files=" + (files != null ? java.util.Arrays.asList(files) : null) + " context=" + context); return files; } else { @@ -295,6 +299,23 @@ } return null; } + @CheckForNull private FileObject[] findTestSourcesFOs(@NonNull Lookup context, boolean allowFolders, boolean strict) { + TYPE: for (String testType : project.supportedTestTypes()) { + FileObject testSrcDir = project.getTestSourceDirectory(testType); + if (testSrcDir != null) { + FileObject[] files = ActionUtils.findSelectedFiles(context, testSrcDir, null, strict); + if (files != null) { + for (FileObject file : files) { + if (!(file.hasExt("java") || allowFolders && file.isFolder())) { + break TYPE; + } + } + return files; + } + } + } + return null; + } @CheckForNull private TestSources findTestMethodSources(@NonNull Lookup context) { SingleMethod meth = context.lookup(SingleMethod.class); if (meth != null) { @@ -328,12 +349,16 @@ /** Find tests corresponding to selected sources. */ - private TestSources findTestSourcesForSources(Lookup context) { + TestSources findTestSourcesForSources(Lookup context) { String testType = "unit"; // NOI18N FileObject[] sourceFiles = findSources(context); if (sourceFiles == null) { + // no source file selected. try folders + sourceFiles = findSources(context, true, true); + if (sourceFiles == null) { return null; } + } FileObject testSrcDir = project.getTestSourceDirectory(testType); if (testSrcDir == null) { return null; @@ -347,11 +372,69 @@ if (matches != null) { return new TestSources(matches, testType, testSrcDir, null); } else { + // no test files found. The selected FOs must be folders under source packages + ArrayList testFOs = new ArrayList(); + for (FileObject file : sourceFiles) { + if (file.isFolder()) { + String relativePath = FileUtil.getRelativePath(srcDir, file); + if (relativePath != null && !relativePath.isEmpty()) { + FileObject testFO = FileUtil.toFileObject(new File(FileUtil.toFile(testSrcDir).getPath().concat(File.separator).concat(relativePath))); + if (testFO != null && testFO.getChildren().length != 0) { + testFOs.add(testFO); + } + } + } + } + if (testFOs.isEmpty()) { return null; } + return new TestSources(testFOs.toArray(new FileObject[testFOs.size()]), testType, testSrcDir, null); } } + } + /** Find tests corresponding to selected files. + * Selected files might be under Source and/or Test Packages + */ + @CheckForNull TestSources findTestSourcesForFiles(Lookup context) { + String testType = "unit"; // NOI18N + FileObject[] sourcesFOs = findSources(context, false, false); + FileObject[] testSourcesFOs = findTestSourcesFOs(context, false, false); + HashSet testFiles = new HashSet(); + FileObject testRoot = project.getTestSourceDirectory(testType); + if (testRoot == null) { + return null; + } + if (testSourcesFOs == null) { + return findTestSources(context, true); + } else { + if (sourcesFOs == null) { + return findTestSources(context, false); + } else { + testFiles.addAll(Arrays.asList(testSourcesFOs)); + //Try to find the test under the test roots + FileObject srcRoot = project.getSourceDirectory(); + FileObject[] files2 = ActionUtils.regexpMapFiles(sourcesFOs, srcRoot, SRCDIRJAVA, testRoot, SUBST, true); + if (files2 != null) { + for (FileObject fo : files2) { + if (!testFiles.contains(fo)) { + testFiles.add(fo); + } + } + } + FileObject[] files2NG = ActionUtils.regexpMapFiles(sourcesFOs, srcRoot, SRCDIRJAVA, testRoot, SUBSTNG, true); + if (files2NG != null) { + for (FileObject fo : files2NG) { + if (!testFiles.contains(fo)) { + testFiles.add(fo); + } + } + } + } + } + return testFiles.isEmpty() ? null : new TestSources(testFiles.toArray(new FileObject[testFiles.size()]), testType, testRoot, null); + } + @Messages("MSG_no_source=No source to operate on.") public void invokeAction(final String command, final Lookup context) throws IllegalArgumentException { if (!canRunNoLock(command, project.getTestUserDirLockFile())) { @@ -411,8 +494,10 @@ TestSources testSources = findTestSourcesForSources(context); if (testSources == null) { testSources = findTestSources(context, true); - + if(testSources == null) { + testSources = findTestSourcesForFiles(context); } + } p.setProperty("continue.after.failing.tests", "true"); //NOI18N targetNames = setupTestSingle(p, testSources); } else if (command.equals(COMMAND_DEBUG_TEST_SINGLE)) { Index: apisupport.ant/test/unit/src/org/netbeans/modules/apisupport/project/ui/ModuleActionsTest.java --- apisupport.ant/test/unit/src/org/netbeans/modules/apisupport/project/ui/ModuleActionsTest.java +++ apisupport.ant/test/unit/src/org/netbeans/modules/apisupport/project/ui/ModuleActionsTest.java @@ -103,4 +103,64 @@ assertEquals("null", String.valueOf(a.findTestSources(Lookups.fixed(oneTest, r), true))); } + public void testFindTestSourcesForSources() throws Exception { + NbModuleProject p = generateStandaloneModule("p"); + FileObject source = p.getSourceDirectory(); + FileObject one = FileUtil.createData(source, "p/One.java"); + FileObject r = FileUtil.createData(source, "p/r.png"); + FileObject other = FileUtil.createData(source, "p/Other.java"); + FileObject pkg = source.getFileObject("p"); + FileObject third = FileUtil.createData(source, "p2/Third.java"); + + FileObject test = p.getTestSourceDirectory("unit"); + FileObject oneTest = FileUtil.createData(test, "p/OneTest.java"); + FileObject otherTest = FileUtil.createData(test, "p/OtherTest.java"); + FileObject thirdTest = FileUtil.createData(test, "p2/ThirdTest.java"); + + ModuleActions a = new ModuleActions(p); + assertEquals("null", String.valueOf(a.findTestSourcesForSources(Lookup.EMPTY))); + assertEquals("unit:p/OneTest.java", String.valueOf(a.findTestSourcesForSources(Lookups.singleton(one)))); + assertEquals("unit:p/OneTest.java,p/OtherTest.java", String.valueOf(a.findTestSourcesForSources(Lookups.fixed(one, other)))); + assertEquals("unit:p/**", String.valueOf(a.findTestSourcesForSources(Lookups.singleton(pkg)))); + assertEquals("null", String.valueOf(a.findTestSourcesForSources(Lookups.singleton(r)))); + assertEquals("null", String.valueOf(a.findTestSourcesForSources(Lookups.fixed(one, r)))); + assertEquals("null", String.valueOf(a.findTestSourcesForSources(Lookup.EMPTY))); + assertEquals("unit:p/OneTest.java", String.valueOf(a.findTestSourcesForSources(Lookups.singleton(one)))); + assertEquals("unit:p/OneTest.java,p/OtherTest.java", String.valueOf(a.findTestSourcesForSources(Lookups.fixed(one, other)))); + assertEquals("null", String.valueOf(a.findTestSourcesForSources(Lookups.singleton(r)))); + assertEquals("null", String.valueOf(a.findTestSourcesForSources(Lookups.fixed(one, r)))); } + + public void testFindTestSourcesForFiles() throws Exception { + NbModuleProject p = generateStandaloneModule("p"); + FileObject source = p.getSourceDirectory(); + FileObject one = FileUtil.createData(source, "p/One.java"); + FileObject r = FileUtil.createData(source, "p/r.png"); + FileObject other = FileUtil.createData(source, "p/Other.java"); + FileObject pkg = source.getFileObject("p"); + FileObject third = FileUtil.createData(source, "p2/Third.java"); + + FileObject test = p.getTestSourceDirectory("unit"); + FileObject oneTest = FileUtil.createData(test, "p/OneTest.java"); + FileObject otherTest = FileUtil.createData(test, "p/OtherTest.java"); + FileObject thirdTest = FileUtil.createData(test, "p2/ThirdTest.java"); + + ModuleActions a = new ModuleActions(p); + assertEquals("null", String.valueOf(a.findTestSourcesForFiles(Lookup.EMPTY))); + String actual = String.valueOf(a.findTestSourcesForFiles(Lookups.fixed(oneTest, other, third))); + String testType = "unit"; + String expOne = "p/OneTest.java"; + String expOther = "p/OtherTest.java"; + String expThird = "p2/ThirdTest.java"; + assertTrue(actual.startsWith(testType.concat(":"))); + assertTrue(actual.contains(expOne)); + assertTrue(actual.contains(expOther)); + assertTrue(actual.contains(expThird)); + + actual = String.valueOf(a.findTestSourcesForFiles(Lookups.fixed(one, otherTest))); + assertTrue(actual.startsWith(testType.concat(":"))); + assertTrue(actual.contains(expOne)); + assertTrue(actual.contains(expOther)); + } + +} Index: j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/resources/build-impl.xsl --- j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/resources/build-impl.xsl +++ j2ee.clientproject/src/org/netbeans/modules/j2ee/clientproject/resources/build-impl.xsl @@ -2368,7 +2368,7 @@ have.tests init,compile-test,-pre-test-run - + Index: j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/resources/build-impl.xsl --- j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/resources/build-impl.xsl +++ j2ee.ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/resources/build-impl.xsl @@ -2345,7 +2345,7 @@ have.tests init,compile-test,-pre-test-run - + Index: java.api.common/src/org/netbeans/modules/java/api/common/project/BaseActionProvider.java --- java.api.common/src/org/netbeans/modules/java/api/common/project/BaseActionProvider.java +++ java.api.common/src/org/netbeans/modules/java/api/common/project/BaseActionProvider.java @@ -483,13 +483,21 @@ if (targetNames == null) { return; } + final String command2execute; + if(COMMAND_TEST_SINGLE.equals(command) && targetNames.length == 1 && targetNames[0].equals(COMMAND_TEST)) { + //multiple files or package(s) selected so we need to call test target instead of test-single + command2execute = COMMAND_TEST; + p.put("nb.internal.action.name", command2execute); + } else { + command2execute = command; + } if (isCompileOnSaveEnabled) { - if (COMMAND_BUILD.equals(command) && !allowAntBuild()) { + if (COMMAND_BUILD.equals(command2execute) && !allowAntBuild()) { showBuildActionWarning(context); return ; } Map execProperties = new HashMap(); - execProperties.put("nb.internal.action.name", command); + execProperties.put("nb.internal.action.name", command2execute); copyMultiValue(ProjectProperties.RUN_JVM_ARGS, execProperties); prepareWorkDir(execProperties); @@ -516,7 +524,7 @@ String url = p.getProperty("applet.url"); execProperties.put("applet.url", url); execProperties.put(JavaRunner.PROP_EXECUTE_FILE, file); - prepareSystemProperties(execProperties, command, context, false); + prepareSystemProperties(execProperties, command2execute, context, false); task = JavaRunner.execute(targetNames[0], execProperties); } @@ -525,50 +533,50 @@ } return; } - if (!isServerExecution() && (COMMAND_RUN.equals(command) || COMMAND_DEBUG.equals(command) || COMMAND_DEBUG_STEP_INTO.equals(command) || COMMAND_PROFILE.equals(command))) { - prepareSystemProperties(execProperties, command, context, false); + if (!isServerExecution() && (COMMAND_RUN.equals(command2execute) || COMMAND_DEBUG.equals(command2execute) || COMMAND_DEBUG_STEP_INTO.equals(command2execute) || COMMAND_PROFILE.equals(command2execute))) { + prepareSystemProperties(execProperties, command2execute, context, false); AtomicReference _task = new AtomicReference(); - bypassAntBuildScript(command, context, execProperties, _task); + bypassAntBuildScript(command2execute, context, execProperties, _task); task = _task.get(); return ; } // for example RUN_SINGLE Java file with Servlet must be run on server and not locally boolean serverExecution = p.getProperty(PROPERTY_RUN_SINGLE_ON_SERVER) != null; p.remove(PROPERTY_RUN_SINGLE_ON_SERVER); - if (!serverExecution && (COMMAND_RUN_SINGLE.equals(command) || COMMAND_DEBUG_SINGLE.equals(command) || COMMAND_PROFILE_SINGLE.equals(command))) { - prepareSystemProperties(execProperties, command, context, false); - if (COMMAND_RUN_SINGLE.equals(command)) { + if (!serverExecution && (COMMAND_RUN_SINGLE.equals(command2execute) || COMMAND_DEBUG_SINGLE.equals(command2execute) || COMMAND_PROFILE_SINGLE.equals(command2execute))) { + prepareSystemProperties(execProperties, command2execute, context, false); + if (COMMAND_RUN_SINGLE.equals(command2execute)) { execProperties.put(JavaRunner.PROP_CLASSNAME, p.getProperty("run.class")); - } else if (COMMAND_DEBUG_SINGLE.equals(command)) { + } else if (COMMAND_DEBUG_SINGLE.equals(command2execute)) { execProperties.put(JavaRunner.PROP_CLASSNAME, p.getProperty("debug.class")); } else { execProperties.put(JavaRunner.PROP_CLASSNAME, p.getProperty("profile.class")); } AtomicReference _task = new AtomicReference(); - bypassAntBuildScript(command, context, execProperties, _task); + bypassAntBuildScript(command2execute, context, execProperties, _task); task = _task.get(); return; } String buildDir = evaluator.getProperty(ProjectProperties.BUILD_DIR); - if (COMMAND_TEST_SINGLE.equals(command) || COMMAND_DEBUG_TEST_SINGLE.equals(command) || COMMAND_PROFILE_TEST_SINGLE.equals(command)) { + if (COMMAND_TEST_SINGLE.equals(command2execute) || COMMAND_DEBUG_TEST_SINGLE.equals(command2execute) || COMMAND_PROFILE_TEST_SINGLE.equals(command2execute)) { @SuppressWarnings("MismatchedReadAndWriteOfArray") FileObject[] files = findTestSources(context, true); try { - prepareSystemProperties(execProperties, command, context, true); + prepareSystemProperties(execProperties, command2execute, context, true); execProperties.put(JavaRunner.PROP_EXECUTE_FILE, files[0]); if (buildDir != null) { // #211543 execProperties.put("tmp.dir", updateHelper.getAntProjectHelper().resolvePath(buildDir)); } - updateJavaRunnerClasspath(command, execProperties); + updateJavaRunnerClasspath(command2execute, execProperties); task = - JavaRunner.execute(command.equals(COMMAND_TEST_SINGLE) ? JavaRunner.QUICK_TEST : (COMMAND_DEBUG_TEST_SINGLE.equals(command) ? JavaRunner.QUICK_TEST_DEBUG :JavaRunner.QUICK_TEST_PROFILE), + JavaRunner.execute(command2execute.equals(COMMAND_TEST_SINGLE) ? JavaRunner.QUICK_TEST : (COMMAND_DEBUG_TEST_SINGLE.equals(command2execute) ? JavaRunner.QUICK_TEST_DEBUG :JavaRunner.QUICK_TEST_PROFILE), execProperties); } catch (IOException ex) { Exceptions.printStackTrace(ex); } return; } - if (SingleMethod.COMMAND_RUN_SINGLE_METHOD.equals(command) || SingleMethod.COMMAND_DEBUG_SINGLE_METHOD.equals(command)) { + if (SingleMethod.COMMAND_RUN_SINGLE_METHOD.equals(command2execute) || SingleMethod.COMMAND_DEBUG_SINGLE_METHOD.equals(command2execute)) { SingleMethod methodSpec = findTestMethods(context)[0]; try { execProperties.put("methodname", methodSpec.getMethodName());//NOI18N @@ -576,9 +584,9 @@ if (buildDir != null) { execProperties.put("tmp.dir",updateHelper.getAntProjectHelper().resolvePath(buildDir)); } - updateJavaRunnerClasspath(command, execProperties); + updateJavaRunnerClasspath(command2execute, execProperties); task = - JavaRunner.execute(command.equals(SingleMethod.COMMAND_RUN_SINGLE_METHOD) ? JavaRunner.QUICK_TEST : JavaRunner.QUICK_TEST_DEBUG, + JavaRunner.execute(command2execute.equals(SingleMethod.COMMAND_RUN_SINGLE_METHOD) ? JavaRunner.QUICK_TEST : JavaRunner.QUICK_TEST_DEBUG, execProperties); } catch (IOException ex) { Exceptions.printStackTrace(ex); @@ -586,12 +594,12 @@ return; } } - collectStartupExtenderArgs(p, command); - Set concealedProperties = collectAdditionalProperties(p, command, context); + collectStartupExtenderArgs(p, command2execute); + Set concealedProperties = collectAdditionalProperties(p, command2execute, context); if (targetNames.length == 0) { targetNames = null; } - if (isCompileOnSaveEnabled && !NO_SYNC_COMMANDS.contains(command)) { + if (isCompileOnSaveEnabled && !NO_SYNC_COMMANDS.contains(command2execute)) { p.put("nb.wait.for.caches", "true"); } final Callback cb = getCallback(); @@ -607,7 +615,7 @@ DialogDisplayer.getDefault().notify(nd); } else { if (cb2 != null) { - cb2.antTargetInvocationStarted(command, context); + cb2.antTargetInvocationStarted(command2execute, context); } try { task = ActionUtils.runTarget(buildFo, targetNames, p, concealedProperties); @@ -623,19 +631,19 @@ } } finally { if (cb2 != null) { - cb2.antTargetInvocationFinished(command, context, task.result()); + cb2.antTargetInvocationFinished(command2execute, context, task.result()); } } } }); } catch (IOException ex) { if (cb2 != null) { - cb2.antTargetInvocationFailed(command, context); + cb2.antTargetInvocationFailed(command2execute, context); } throw ex; } catch (RuntimeException ex) { if (cb2 != null) { - cb2.antTargetInvocationFailed(command, context); + cb2.antTargetInvocationFailed(command2execute, context); } throw ex; } @@ -800,11 +808,17 @@ targetNames = getCommands().get(command); } else if ( command.equals( COMMAND_TEST_SINGLE ) ) { p.setProperty("ignore.failing.tests", "true"); //NOI18N - final FileObject[] files = findTestSources(context, true); + final FileObject[] files = findTestSourcesForFiles(context); if (files == null) { return null; } + if(files.length == 1 && files[0].isData()) { + //one file or a package containing one file selected targetNames = setupTestSingle(p, files); + } else { + //multiple files or package(s) selected + targetNames = setupTestFilesOrPackages(p, files); + } } else if ( command.equals( COMMAND_DEBUG_TEST_SINGLE ) ) { final FileObject[] files = findTestSources(context, true); if (files == null) { @@ -1194,6 +1208,14 @@ return new String[] {"test-single"}; // NOI18N } + private String[] setupTestFilesOrPackages(Properties p, FileObject[] files) { + if (files != null) { + FileObject root = getRoot(projectTestRoots.getRoots(), files[0]); + p.setProperty("includes", ActionUtils.antIncludesList(files, root).replace("**", "**/*Test.java")); // NOI18N + } + return new String[]{"test"}; // NOI18N + } + private String[] setupDebugTestSingle(Properties p, FileObject[] files) { FileObject[] testSrcPath = projectTestRoots.getRoots(); FileObject root = getRoot(testSrcPath, files[0]); @@ -1271,8 +1293,8 @@ || findSourcesAndPackages( context, projectTestRoots.getRoots()) != null; } else if ( command.equals( COMMAND_TEST_SINGLE ) ) { - FileObject[] fos = findTestSources(context, true); - return fos != null && fos.length == 1; + FileObject[] fos = findTestSourcesForFiles(context); + return fos != null; } else if ( command.equals( COMMAND_DEBUG_TEST_SINGLE ) ) { FileObject[] fos = findTestSources(context, true); @@ -1373,9 +1395,21 @@ */ @org.netbeans.api.annotations.common.SuppressWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS") private @CheckForNull FileObject[] findSources(Lookup context) { + return findSources(context, true, false); + } + + /** + * Find selected source files + * + * @param context the lookup in which files should be found + * @param strict if true, all files in the selection have to be accepted + * @param findInPackages if true, all files under a selected package in the selection will also be checked + */ + @org.netbeans.api.annotations.common.SuppressWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS") + private @CheckForNull FileObject[] findSources(Lookup context, boolean strict, boolean findInPackages) { FileObject[] srcPath = projectSourceRoots.getRoots(); for (int i=0; i< srcPath.length; i++) { - FileObject[] files = ActionUtils.findSelectedFiles(context, srcPath[i], ".java", true); // NOI18N + FileObject[] files = ActionUtils.findSelectedFiles(context, srcPath[i], findInPackages ? null : ".java", strict); // NOI18N if (files != null) { return files; } @@ -1416,34 +1450,114 @@ */ @org.netbeans.api.annotations.common.SuppressWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS") private @CheckForNull FileObject[] findTestSources(Lookup context, boolean checkInSrcDir) { + return findTestSources(context, checkInSrcDir, true, false); + } + + /** + * Find selected tests and/or tests which belong to selected source files + * + * @param context the lookup in which files should be found + * @param checkInSrcDir if true, tests which belong to selected source files will be searched for + * @param strict if true, all files in the selection have to be accepted + * @param findInPackages if true, all files under a selected package in the selection will also be checked + */ + @org.netbeans.api.annotations.common.SuppressWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS") + private @CheckForNull FileObject[] findTestSources(Lookup context, boolean checkInSrcDir, boolean strict, boolean findInPackages) { //XXX: Ugly, should be rewritten - FileObject[] testSrcPath = projectTestRoots.getRoots(); - for (int i=0; i< testSrcPath.length; i++) { - FileObject[] files = ActionUtils.findSelectedFiles(context, testSrcPath[i], ".java", true); // NOI18N + FileObject[] testSrcPaths = projectTestRoots.getRoots(); + for (FileObject testSrcPath : testSrcPaths) { + FileObject[] files = ActionUtils.findSelectedFiles(context, testSrcPath, findInPackages ? null : ".java", strict); // NOI18N + ArrayList testFOs = new ArrayList<>(); if (files != null) { - return files; + for (FileObject file : files) { + if ((file.hasExt("java") || findInPackages && file.isFolder())) { + testFOs.add(file); } } - if (checkInSrcDir && testSrcPath.length>0) { - FileObject[] files = findSources (context); + return testFOs.toArray(new FileObject[testFOs.size()]); + } + } + if (checkInSrcDir && testSrcPaths.length>0) { + FileObject[] files = findSources (context, strict, findInPackages); if (files != null) { //Try to find the test under the test roots FileObject srcRoot = getRoot(projectSourceRoots.getRoots(),files[0]); - for (int i=0; i testFOs = new ArrayList<>(); + if (files != null) { + for (FileObject file : files) { + if (findInPackages && file.isFolder()) { + String relativePath = FileUtil.getRelativePath(srcRoot, file); + if (relativePath != null) { + for (FileObject testSrcPath : testSrcPaths) { + FileObject testFO = FileUtil.toFileObject(new File(FileUtil.toFile(testSrcPath).getPath().concat(File.separator).concat(relativePath))); + if (testFO != null) { + testFOs.add(testFO); } } + } + } + } + return testFOs.toArray(new FileObject[testFOs.size()]); + } + } + } return null; } + /** + * Find selected tests and tests which belong to selected source files + * when package(s) or multiple files are selected. + * + * @param context the lookup in which files should be found + */ + @org.netbeans.api.annotations.common.SuppressWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS") + private @CheckForNull FileObject[] findTestSourcesForFiles(Lookup context) { + FileObject[] sourcesFOs = findSources(context, false, true); + FileObject[] testSourcesFOs = findTestSources(context, false, false, true); + HashSet testFiles = new HashSet<>(); + if(testSourcesFOs == null) { + return findTestSources(context, true, false, true); + } else { + if(sourcesFOs == null) { + return testSourcesFOs; + } else { + testFiles.addAll(Arrays.asList(testSourcesFOs)); + //Try to find the test under the test roots + FileObject srcRoot = getRoot(projectSourceRoots.getRoots(),sourcesFOs[0]); + for (FileObject testRoot : projectTestRoots.getRoots()) { + FileObject[] files2 = ActionUtils.regexpMapFiles(sourcesFOs, srcRoot, SRCDIRJAVA, testRoot, SUBST, true); + if (files2 != null) { + for (FileObject fo : files2) { + if(!testFiles.contains(fo)) { + testFiles.add(fo); + } + } + } + FileObject[] files2NG = ActionUtils.regexpMapFiles(sourcesFOs, srcRoot, SRCDIRJAVA, testRoot, SUBSTNG, true); + if (files2NG != null) { + for (FileObject fo : files2NG) { + if(!testFiles.contains(fo)) { + testFiles.add(fo); + } + } + } + } + } + } + return testFiles.isEmpty() ? null : testFiles.toArray(new FileObject[testFiles.size()]); + } /** * Finds single method specification objects corresponding to JUnit test Index: java.j2seproject/src/org/netbeans/modules/java/j2seproject/resources/build-impl.xsl --- java.j2seproject/src/org/netbeans/modules/java/j2seproject/resources/build-impl.xsl +++ java.j2seproject/src/org/netbeans/modules/java/j2seproject/resources/build-impl.xsl @@ -2397,7 +2397,7 @@ have.tests init,compile-test,-pre-test-run - + Index: java.project/src/org/netbeans/spi/java/project/support/ui/Bundle.properties --- java.project/src/org/netbeans/spi/java/project/support/ui/Bundle.properties +++ java.project/src/org/netbeans/spi/java/project/support/ui/Bundle.properties @@ -75,3 +75,7 @@ ACSD_excludesLabel=Excludes pattern ACSN_IncludeExcludeVisualizerPanel=Include Exclude Panel ACSD_IncludeExcludeVisualizerPanel=Include and Exclude patterns for project + +# Name of package action +# {0} - # of selected packages +LBL_TestPackageAction_Name=T&est {0,choice,0#Package|1#Package|1()); + testPackageAction = FileSensitiveActions.fileCommandAction(ActionProvider.COMMAND_TEST_SINGLE, NbBundle.getMessage(PackageViewChildren.class, "LBL_TestPackageAction_Name"), null); this.root = group.getRootFolder(); this.group = group; visibility_refresh = VISIBILITY_CHANGE_RP.create(new Runnable() { @@ -757,6 +760,7 @@ else if ( superActions[i] instanceof FileSystemAction ) { actionList.add (null); // insert separator and new action actionList.add (FileSensitiveActions.fileCommandAction(ActionProvider.COMMAND_COMPILE_SINGLE, LBL_CompilePackage_Action(), null)); + actionList.add (testPackageAction); actionList.addAll((List) org.openide.util.Utilities.actionsForPath("Projects/package/Actions")); } Index: maven/src/org/netbeans/modules/maven/execute/ActionToGoalUtils.java --- maven/src/org/netbeans/modules/maven/execute/ActionToGoalUtils.java +++ maven/src/org/netbeans/modules/maven/execute/ActionToGoalUtils.java @@ -46,9 +46,12 @@ import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; +import java.net.URI; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -72,7 +75,9 @@ import org.netbeans.spi.project.ActionProvider; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.loaders.DataObject; import org.openide.util.Lookup; +import org.openide.util.Utilities; import org.openide.windows.InputOutput; /** @@ -169,11 +174,51 @@ rc.setActivatedProfiles(acts); Map props = new HashMap(rc.getProperties()); props.putAll(configs.getActiveConfiguration().getProperties()); + if (ActionProvider.COMMAND_TEST_SINGLE.equals(action)) { + String testProperty = props.get("test"); + // multiple files were selected from both source and test packages and "Test Files" action was invoked on them + if (testProperty != null && testProperty.equals("${packageClassName}")) { + Collection candidates = lookup.lookupAll(FileObject.class); + if (candidates.isEmpty()) { // should not be for DataNode selections, but for compatibility + Collection compatibilityCandidates = lookup.lookupAll(DataObject.class); + if (compatibilityCandidates.isEmpty()) {// shortcut - just not a file selection at all + List _candidates = new ArrayList(); + for (DataObject d : compatibilityCandidates) { + _candidates.add(d.getPrimaryFile()); + } + candidates = _candidates; + } + } + HashSet test = new HashSet(); + addSelectedFiles(project, false, candidates, test); + addSelectedFiles(project, true, candidates, test); + String toString = test.toString().replace(" ", ""); + props.put("test", toString.substring(1, toString.length() - 1)); + } + } rc.addProperties(props); } return rc; } + private static void addSelectedFiles(NbMavenProjectImpl project, boolean testRoots, Collection candidates, HashSet test) { + URI[] roots = project.getSourceRoots(testRoots); + for (URI uri : roots) { + FileObject root = FileUtil.toFileObject(Utilities.toFile(uri)); + for (FileObject candidate : candidates) { + String relativePath = FileUtil.getRelativePath(root, candidate); + if (relativePath != null) { + if(testRoots) { + relativePath = relativePath.replace(".java", "").replace('/', '.'); + } else { + relativePath = relativePath.replace(".java", "Test").replace('/', '.'); + } + test.add(relativePath); + } + } + } + } + public static boolean isActionEnable(String action, NbMavenProjectImpl project, Lookup lookup) { M2ConfigProvider configs = project.getLookup().lookup(M2ConfigProvider.class); Index: projectui/src/org/netbeans/modules/project/ui/actions/Bundle.properties --- projectui/src/org/netbeans/modules/project/ui/actions/Bundle.properties +++ projectui/src/org/netbeans/modules/project/ui/actions/Bundle.properties @@ -80,9 +80,11 @@ LBL_RunMainProjectAction_Name=&Run {0,choice,-1#Main Project|0#Project|1#Project ({1})|1<{0} Projects} +# Name of 1-off actions +# {0} - # of selected files LBL_RunSingleAction_Name=Run &File # {0,choice,0#File|1#"{1}"|1 have.tests init,compile-test,-pre-test-run - +