/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;

import junit.framework.Test;

public class ExclusionPatternsTests extends ModifyingResourceTests {
	IJavaProject project;
public ExclusionPatternsTests(String name) {
	super(name);
}
protected void setClasspath(String[] sourceFoldersAndExclusionPatterns) throws JavaModelException {
	this.project.setRawClasspath(createClasspath(sourceFoldersAndExclusionPatterns, false/*no inclusion*/, true/*exclusion*/), null);
}
@Override
protected void setUp() throws Exception {
	super.setUp();
	this.project = createJavaProject("P", new String[] {"src"}, "bin");
	startDeltas();
}

// Use this static initializer to specify subset for tests
// All specified tests which do not belong to the class are skipped...
static {
//		TESTS_NAMES = new String[] { "testCreateExcludedPackage2" };
//		TESTS_NUMBERS = new int[] { 2, 12 };
//		TESTS_RANGE = new int[] { 16, -1 };
}
public static Test suite() {
	return buildModelTestSuite(ExclusionPatternsTests.class);
}

@Override
protected void tearDown() throws Exception {
	stopDeltas();
	deleteProject("P");
	super.tearDown();
}
/*
 * Ensure that adding an exclusion on a compilation unit
 * makes it disappear from the children of its package and it is added to the non-java resources.
 */
public void testAddExclusionOnCompilationUnit() throws CoreException {
	createFolder("/P/src/p");
	createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	clearDeltas();
	setClasspath(new String[] {"/P/src", "**/A.java"});

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
		"	src[*]: {ADDED TO CLASSPATH | REMOVED FROM CLASSPATH}\n" +
		"	ResourceDelta(/P/.classpath)[*]"
	);

	IPackageFragment pkg = getPackage("/P/src/p");
	assertSortedElementsEqual(
		"Unexpected children",
		"",
		pkg.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"A.java",
		pkg.getNonJavaResources());
}
/*
 * Ensure that adding an exclusion on a folder directly under a project (and prj=src)
 * makes it appear as a non-java resources.
 * (regression test for bug 29374 Excluded folder on project not returned by Java Model)
 */
public void testAddExclusionOnFolderUnderProject() throws CoreException {
	try {
		IJavaProject javaProject = createJavaProject("P1", new String[] {""}, "");
		createFolder("/P1/doc");

		clearDeltas();
		javaProject.setRawClasspath(createClasspath(new String[] {"/P1", "doc/"}, false/*no inclusion*/, true/*exclusion*/), null);

		assertDeltas(
			"Unexpected deltas",
			"P1[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
			"	<project root>[*]: {ADDED TO CLASSPATH | REMOVED FROM CLASSPATH}\n" +
			"	ResourceDelta(/P1/.classpath)[*]"
		);

		IPackageFragmentRoot root = getPackageFragmentRoot("/P1");
		assertSortedElementsEqual(
			"Unexpected children",
			"<default> [in <project root> [in P1]]",
			root.getChildren());

		assertResourceNamesEqual(
			"Unexpected non-java resources of project",
			".classpath\n" +
			".project\n" +
			"doc",
			javaProject.getNonJavaResources());
	} finally {
		deleteProject("P1");
	}
}
/*
 * Ensure that adding an exclusion on a package
 * makes it disappear from the children of its package fragment root
 * and it is added to the non-java resources.
 */
public void testAddExclusionOnPackage() throws CoreException {
	createFolder("/P/src/p");

	clearDeltas();
	setClasspath(new String[] {"/P/src", "p/"});

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
		"	src[*]: {ADDED TO CLASSPATH | REMOVED FROM CLASSPATH}\n" +
		"	ResourceDelta(/P/.classpath)[*]"
	);

	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");
	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"p",
		root.getNonJavaResources());
}
/*
 * Ensure that adding an exclusion on a primary working copy
 * makes it disappear from the children of its package and it is added to the non-java resources.
 */
public void testAddExclusionOnPrimaryWorkingCopy() throws CoreException {
	createFolder("/P/src/p");
	createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	ICompilationUnit workingCopy = null;
	try {
		workingCopy = getCompilationUnit("/P/src/p/A.java");
		workingCopy.becomeWorkingCopy(null);

		clearDeltas();
		setClasspath(new String[] {"/P/src", "**/A.java"});

		assertDeltas(
			"Unexpected deltas",
			"P[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
			"	src[*]: {ADDED TO CLASSPATH | REMOVED FROM CLASSPATH}\n" +
			"	ResourceDelta(/P/.classpath)[*]"
		);

		IPackageFragment pkg = getPackage("/P/src/p");
		assertSortedElementsEqual(
			"Unexpected children",
			"",
			pkg.getChildren());

		assertResourceNamesEqual(
			"Unexpected non-java resources",
			"A.java",
			pkg.getNonJavaResources());
	} finally {
		if (workingCopy != null) {
			workingCopy.discardWorkingCopy();
		}
	}
}
/*
 * Ensure that adding a file to a folder that is excluded reports the correct delta.
 * (regression test for bug 29621 Wrong Delta When Adding to Filtered Folder)
 */
public void testAddToExcludedFolder() throws CoreException {
	createFolder("/P/src/icons");

	// exclude folder and its contents
	setClasspath(new String[] {"/P/src", "icons/"});

	clearDeltas();
	createFile("/P/src/icons/my.txt", "");
	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CONTENT}\n" +
		"		ResourceDelta(/P/src/icons)[*]"
	);

	clearDeltas();
	deleteFile("/P/src/icons/my.txt");
	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CONTENT}\n" +
		"		ResourceDelta(/P/src/icons)[*]"
	);
}
/*
 * Ensure that creating an excluded compilation unit
 * doesn't make it appear as a child of its package but it is a non-java resource.
 */
public void testCreateExcludedCompilationUnit() throws CoreException {
	setClasspath(new String[] {"/P/src", "**/A.java"});
	createFolder("/P/src/p");
	IPackageFragment pkg = getPackage("/P/src/p");

	clearDeltas();
	pkg.createCompilationUnit(
		"A.java",
		"package p;\n" +
		"public class A {\n" +
		"}",
		false,
		null);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN}\n" +
		"		p[*]: {CONTENT}\n" +
		"			ResourceDelta(/P/src/p/A.java)[+]"
	);

	assertSortedElementsEqual(
		"Unexpected children",
		"",
		pkg.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"A.java",
		pkg.getNonJavaResources());
}
/*
 * Ensure that crearing an excluded package
 * doesn't make it appear as a child of its package fragment root but it is a non-java resource.
 */
public void testCreateExcludedPackage() throws CoreException {
	setClasspath(new String[] {"/P/src", "p/"});
	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");

	clearDeltas();
	root.createPackageFragment("p", false, null);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CONTENT}\n" +
		"		ResourceDelta(/P/src/p)[+]"
	);

	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"p",
		root.getNonJavaResources());
}
/*
 * Ensure that creating an excluded package doesn't make it appear as a child of its package fragment root but it is a non-java resource.
 * (regression test for bug 65637 [model] Excluded package still in Java model)
 */
public void testCreateExcludedPackage2() throws CoreException {
	setClasspath(new String[] {"/P/src", "org/*|org/eclipse/*"});

	// Trigger population of cache to check if it is properly invalidated by the delta processor.
	// See http://bugs.eclipse.org/500714
	getPackageFragmentRoot("/P/src").getChildren();

	clearDeltas();
	createFolder("/P/src/org/eclipse/mypack");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CONTENT}\n" +
		"		ResourceDelta(/P/src/org)[+]"
	);

	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");
	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]\n" +
		"org.eclipse.mypack [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"org",
		root.getNonJavaResources());
}
/*
 * Ensure that creating a folder that represents an excluded and included package
 * have the correct delta, Java elements and non-Java resources.
 * (regression test for 67789 Java element delta from refresh contains excluded package)
 */
public void testCreateExcludedAndIncludedPackages() throws CoreException {
	setClasspath(new String[] {"/P/src", "p1/p2/"});
	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");

	clearDeltas();
	createFolder("/P/src/p1/p2");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN}\n" +
		"		p1[+]: {}"
	);

	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]\n" +
		"p1 [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"p2",
		root.getPackageFragment("p1").getNonJavaResources());
}
/*
 * Ensure that creating a file that corresponds to an excluded compilation unit
 * doesn't make it appear as a child of its package but it is a non-java resource.
 */
public void testCreateResourceExcludedCompilationUnit() throws CoreException {
	setClasspath(new String[] {"/P/src", "**/A.java"});
	createFolder("/P/src/p");

	clearDeltas();
	createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN}\n" +
		"		p[*]: {CONTENT}\n" +
		"			ResourceDelta(/P/src/p/A.java)[+]"
	);

	IPackageFragment pkg = getPackage("/P/src/p");
	assertSortedElementsEqual(
		"Unexpected children",
		"",
		pkg.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"A.java",
		pkg.getNonJavaResources());
}
/*
 * Ensure that creating a folder that corresponds to an excluded package
 * doesn't make it appear as a child of its package fragment root but it is a non-java resource.
 */
public void testCreateResourceExcludedPackage() throws CoreException {
	setClasspath(new String[] {"/P/src", "p/"});

	clearDeltas();
	createFolder("/P/src/p");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CONTENT}\n" +
		"		ResourceDelta(/P/src/p)[+]"
	);

	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");
	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"p",
		root.getNonJavaResources());
}
/*
 * Ensures that a cu that is not excluded is on the classpath of the project.
 */
public void testIsOnClasspath1() throws CoreException {
	setClasspath(new String[] {"/P/src", ""});
	createFolder("/P/src/p");
	IFile file = createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);
	assertTrue("Resource should be on classpath", this.project.isOnClasspath(file));

	ICompilationUnit cu = getCompilationUnit("/P/src/p/A.java");
	assertTrue("CU should be on classpath", this.project.isOnClasspath(cu));
}
/*
 * Ensures that a cu that is excluded is not on the classpath of the project.
 */
public void testIsOnClasspath2() throws CoreException {
	setClasspath(new String[] {"/P/src", "**/A.java"});
	createFolder("/P/src/p");
	IFile file = createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);
	assertTrue("Resource should not be on classpath", !this.project.isOnClasspath(file));

	ICompilationUnit cu = getCompilationUnit("/P/src/p/A.java");
	assertTrue("CU should not be on classpath", !this.project.isOnClasspath(cu));
}
/*
 * Ensures that a non-java resource that is not excluded is on the classpath of the project.
 */
public void testIsOnClasspath3() throws CoreException {
	setClasspath(new String[] {"/P/src", ""});
	createFolder("/P/src/p");
	IFile file = createFile("/P/src/p/readme.txt", "");
	assertTrue("Resource should be on classpath", this.project.isOnClasspath(file));
}
/*
 * Ensures that a non-java resource that is excluded is not on the classpath of the project.
 */
public void testIsOnClasspath4() throws CoreException {
	setClasspath(new String[] {"/P/src", "p/**"});
	createFolder("/P/src/p");
	IFile file = createFile("/P/src/p/readme.txt", "");
	assertTrue("Resource should not be on classpath", !this.project.isOnClasspath(file));
}
/*
 * Ensures that an excluded nested source folder doesn't appear as a non-java resource of the outer folder.
 * (regression test for bug 28115 Ubiquitous resource in the JavaModel)
 *
 */
public void testNestedSourceFolder1() throws CoreException {
	setClasspath(new String[] {"/P/src1", "src2/**", "/P/src1/src2", ""});
	createFolder("/P/src1/src2");
	IPackageFragmentRoot root1 = getPackageFragmentRoot("/P/src1");
	assertResourceNamesEqual(
		"Unexpected non-java resources for /P/src1",
		"",
		root1.getNonJavaResources());
}
/*
 * Ensures that adding a .java file in a nested source folder reports
 * a delta on the nested source folder and not on the outer one.
 */
public void testNestedSourceFolder2() throws CoreException {
	setClasspath(new String[] {"/P/src1", "src2/**", "/P/src1/src2", ""});
	createFolder("/P/src1/src2");

	clearDeltas();
	createFile(
		"/P/src1/src2/A.java",
		"public class A {\n" +
		"}"
	);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src1/src2[*]: {CHILDREN}\n" +
		"		<default>[*]: {CHILDREN}\n" +
		"			A.java[+]: {}"
	);
}
/*
 * Ensures that adding a .txt file in a nested source folder reports
 * a resource delta on the nested source folder and not on the outer one.
 */
public void testNestedSourceFolder3() throws CoreException {
	setClasspath(new String[] {"/P/src1", "src2/**", "/P/src1/src2", ""});
	createFolder("/P/src1/src2");

	clearDeltas();
	createFile("/P/src1/src2/readme.txt", "");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src1/src2[*]: {CONTENT}\n" +
		"		ResourceDelta(/P/src1/src2/readme.txt)[+]"
	);
}
/*
 * Ensures that adding a folder in a nested source folder reports
 * a delta on the nested source folder and not on the outer one.
 */
public void testNestedSourceFolder4() throws CoreException {
	setClasspath(new String[] {"/P/src1", "src2/**", "/P/src1/src2", ""});
	createFolder("/P/src1/src2");

	clearDeltas();
	createFolder("/P/src1/src2/p");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src1/src2[*]: {CHILDREN}\n" +
		"		p[+]: {}"
	);
}
/*
 * Ensures that adding a folder in a outer source folder reports
 * a delta on the outer source folder and not on the nested one.
 */
public void testNestedSourceFolder5() throws CoreException {
	setClasspath(new String[] {"/P/src1", "src2/**", "/P/src1/src2", ""});
	createFolder("/P/src1/src2");

	clearDeltas();
	createFolder("/P/src1/p");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src1[*]: {CHILDREN}\n" +
		"		p[+]: {}"
	);
}
/*
 * Ensures that moving a package from an outer source folder to a nested
 * source folder reports a move delta.
 */
public void testNestedSourceFolder6() throws CoreException {
	setClasspath(new String[] {"/P/src1", "src2/**", "/P/src1/src2", ""});
	createFolder("/P/src1/src2");
	createFolder("/P/src1/p");

	clearDeltas();
	moveFolder("/P/src1/p", "/P/src1/src2/p");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src1[*]: {CHILDREN}\n" +
		"		p[-]: {MOVED_TO(p [in src1/src2 [in P]])}\n" +
		"	src1/src2[*]: {CHILDREN}\n" +
		"		p[+]: {MOVED_FROM(p [in src1 [in P]])}"
	);
}
/*
 * Ensure that renaming an excluded compilation unit so that it is not excluded any longer
 * makes it appears as a child of its package and it is removed from the non-java resources.
 */
public void testRenameExcludedCompilationUnit() throws CoreException {
	setClasspath(new String[] {"/P/src", "**/A.java"});
	createFolder("/P/src/p");
	IFile file = createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	clearDeltas();
	file.move(new Path("/P/src/p/B.java"), false, null);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN}\n" +
		"		p[*]: {CHILDREN | CONTENT}\n" +
		"			B.java[+]: {}\n" +
		"			ResourceDelta(/P/src/p/A.java)[-]"
	);

	IPackageFragment pkg = getPackage("/P/src/p");
	assertSortedElementsEqual(
		"Unexpected children",
		"B.java [in p [in src [in P]]]",
		pkg.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"",
		pkg.getNonJavaResources());
}
/*
 * Ensure that renaming an excluded package so that it is not excluded any longer
 * makes it appears as a child of its package fragment root
 * and it is removed from the non-java resources.
 */
public void testRenameExcludedPackage() throws CoreException {
	setClasspath(new String[] {"/P/src", "p/"});
	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");
	IPackageFragment pkg = root.createPackageFragment("p", false, null);

	clearDeltas();
	pkg.getResource().move(new Path("/P/src/q"), false, null);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN | CONTENT}\n" +
		"		q[+]: {}\n" +
		"		ResourceDelta(/P/src/p)[-]"
	);

	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]\n" +
		"q [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"",
		root.getNonJavaResources());
}
/*
 * Ensure that renaming a file that corresponds to an excluded compilation unit so that it is not excluded any longer
 * makes it appears as a child of its package and it is removed from the non-java resources.
 */
public void testRenameResourceExcludedCompilationUnit() throws CoreException {
	setClasspath(new String[] {"/P/src", "**/A.java"});
	createFolder("/P/src/p");
	IFile file = createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	clearDeltas();
	file.move(new Path("/P/src/p/B.java"),  false, null);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN}\n" +
		"		p[*]: {CHILDREN | CONTENT}\n" +
		"			B.java[+]: {}\n" +
		"			ResourceDelta(/P/src/p/A.java)[-]"
	);

	IPackageFragment pkg = getPackage("/P/src/p");
	assertSortedElementsEqual(
		"Unexpected children",
		"B.java [in p [in src [in P]]]",
		pkg.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"",
		pkg.getNonJavaResources());
}
/*
 * Ensure search doesn't find matches in an excluded compilation unit.
 */
public void testSearchWithExcludedCompilationUnit1() throws CoreException {
	setClasspath(new String[] {"/P/src", "**/A.java"});
	createFolder("/P/src/p");
	createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	JavaSearchTests.JavaSearchResultCollector resultCollector = new JavaSearchTests.JavaSearchResultCollector();
	search(
		"A",
		IJavaSearchConstants.TYPE,
		IJavaSearchConstants.DECLARATIONS,
		SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("P")}),
		resultCollector);
	assertEquals(
		"Unexpected matches found",
		"",
		resultCollector.toString());
}
/*
 * Ensure search find matches in a compilation unit that was excluded but that is not any longer.
 */
public void testSearchWithExcludedCompilationUnit2() throws CoreException {
	setClasspath(new String[] {"/P/src", "A.java"});
	createFolder("/P/src/p");
	createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	setClasspath(new String[] {"/P/src", ""});
	JavaSearchTests.JavaSearchResultCollector resultCollector = new JavaSearchTests.JavaSearchResultCollector();
	search(
		"A",
		IJavaSearchConstants.TYPE,
		IJavaSearchConstants.DECLARATIONS,
		SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("P")}),
		resultCollector);
	assertEquals(
		"Unexpected matches found",
		"src/p/A.java p.A [A]",
		resultCollector.toString());
}
/*
 * Ensure that removing a folder that represents an excluded and included package
 * have the correct delta, Java elements and non-Java resources.
 * (regression test for 67789 Java element delta from refresh contains excluded package)
 */
public void testRemoveExcludedAndIncludedPackages() throws CoreException {
	setClasspath(new String[] {"/P/src", "p1/p2/"});
	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");
	createFolder("/P/src/p1/p2");

	clearDeltas();
	deleteFolder("/P/src/p1");

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN}\n" +
		"		p1[-]: {}"
	);

	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"",
		root.getNonJavaResources());
}

/*
 * Ensure that renaming a folder that corresponds to an excluded package
 * so that it is not excluded any longer
 * makes it appears as a child of its package fragment root
 * and it is removed from the non-java resources.
 */
public void testRenameResourceExcludedPackage() throws CoreException {
	setClasspath(new String[] {"/P/src", "p/"});
	IFolder folder = createFolder("/P/src/p");

	clearDeltas();
	folder.move(new Path("/P/src/q"), false, null);

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN}\n" +
		"	src[*]: {CHILDREN | CONTENT}\n" +
		"		q[+]: {}\n" +
		"		ResourceDelta(/P/src/p)[-]"
	);

	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");
	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]\n" +
		"q [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"",
		root.getNonJavaResources());
}
/*
 * Ensure that a potential match in the output folder is not indexed.
 * (regression test for bug 32041 Multiple output folders fooling Java Model)
 */
public void testSearchPotentialMatchInOutput() throws CoreException {
	try {
		JavaCore.run(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				IJavaProject javaProject = createJavaProject("P2", new String[] {}, "bin");
				javaProject.setRawClasspath(createClasspath(new String[] {"/P2", "src/", "/P2/src", ""}, false/*no inclusion*/, true/*exclusion*/), null);
				createFile(
					"/P2/bin/X.java",
					"public class X {\n" +
					"}"
				);
			}
		}, null);

		JavaSearchTests.JavaSearchResultCollector resultCollector = new JavaSearchTests.JavaSearchResultCollector();
		IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] {getJavaProject("P")});
		search(
			"X",
			IJavaSearchConstants.TYPE,
			IJavaSearchConstants.DECLARATIONS,
			scope,
			resultCollector);
		assertEquals("", resultCollector.toString());
	} finally {
		deleteProject("P2");
	}
}
/*
 * Ensure that removing the exclusion on a compilation unit
 * makes it appears as a child of its package and it is removed from the non-java resources.
 */
public void testRemoveExclusionOnCompilationUnit() throws CoreException {
	setClasspath(new String[] {"/P/src", "A.java"});
	createFolder("/P/src/p");
	createFile(
		"/P/src/p/A.java",
		"package p;\n" +
		"public class A {\n" +
		"}"
	);

	clearDeltas();
	setClasspath(new String[] {"/P/src", ""});

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
		"	src[*]: {ADDED TO CLASSPATH | REMOVED FROM CLASSPATH}\n" +
		"	ResourceDelta(/P/.classpath)[*]"
	);

	IPackageFragment pkg = getPackage("/P/src/p");
	assertSortedElementsEqual(
		"Unexpected children",
		"A.java [in p [in src [in P]]]",
		pkg.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"",
		pkg.getNonJavaResources());
}
/*
 * Ensure that removing the exclusion on a package
 * makes it appears as a child of its package fragment root
 * and it is removed from the non-java resources.
 */
public void testRemoveExclusionOnPackage() throws CoreException {
	setClasspath(new String[] {"/P/src", "p"});
	createFolder("/P/src/p");

	clearDeltas();
	setClasspath(new String[] {"/P/src", ""});

	assertDeltas(
		"Unexpected deltas",
		"P[*]: {CHILDREN | CONTENT | RAW CLASSPATH CHANGED | RESOLVED CLASSPATH CHANGED}\n" +
		"	src[*]: {ADDED TO CLASSPATH | REMOVED FROM CLASSPATH}\n" +
		"	ResourceDelta(/P/.classpath)[*]"
	);

	IPackageFragmentRoot root = getPackageFragmentRoot("/P/src");
	assertSortedElementsEqual(
		"Unexpected children",
		"<default> [in src [in P]]\n" +
		"p [in src [in P]]",
		root.getChildren());

	assertResourceNamesEqual(
		"Unexpected non-java resources",
		"",
		root.getNonJavaResources());
}
}
