/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.core.internal.builder; import com.google.dart.engine.utilities.io.FileUtilities2; import com.google.dart.tools.core.AbstractDartCoreTest; import com.google.dart.tools.core.internal.analysis.model.WorkspaceDeltaProcessor; import com.google.dart.tools.core.internal.model.DartIgnoreManager; import com.google.dart.tools.core.mock.MockDelta; import com.google.dart.tools.core.mock.MockFile; import com.google.dart.tools.core.mock.MockFolder; import com.google.dart.tools.core.mock.MockProject; import static com.google.dart.tools.core.DartCore.PACKAGES_DIRECTORY_NAME; import static com.google.dart.tools.core.DartCore.PUBSPEC_FILE_NAME; import org.eclipse.core.runtime.Path; import org.mockito.Mockito; import static org.eclipse.core.resources.IResourceDelta.ADDED; import static org.eclipse.core.resources.IResourceDelta.REMOVED; import java.io.File; import java.io.IOException; // Similar to DeltaProcessorTest but focusing on canonical processing of package changes public class DeltaProcessorCanonicalTest extends AbstractDartCoreTest { private MockProject projectContainer; private DeltaProcessorMockProject project; private File projDir; private File packagesDir; private File pkg1Dir; /** * Test adding and removing a symlinked package in the "packages" directory */ public void test_traverse_package_added_removed() throws Exception { if (!symlinkPackage(projDir)) { return; } // add package MockDelta delta = new MockDelta(projectContainer); delta.add(PACKAGES_DIRECTORY_NAME).add("pkg1", ADDED); DeltaProcessor processor = new DeltaProcessor(project); ProjectUpdater updater = new ProjectUpdater(); processor.addDeltaListener(updater); processor.traverse(delta); updater.applyChanges(); // Canonical locations File pkg1SomeDir = new File(pkg1Dir, "some_folder"); File[] added = new File[] { new File(pkg1Dir, "build.dart"), new File(pkg1Dir, "bar.dart"), new File(pkg1SomeDir, "build.dart"), new File(pkg1SomeDir, "bar.dart")}; project.assertChanged(projectContainer, added, null, null, null); project.assertNoCalls(); // remove package FileUtilities2.deleteSymLink(new File(packagesDir, "pkg1")); delta = new MockDelta(projectContainer); delta.add(PACKAGES_DIRECTORY_NAME).add("pkg1", REMOVED); processor = new DeltaProcessor(project); AnalysisMarkerManager markerManager = Mockito.mock(AnalysisMarkerManager.class); IgnoreResourceFilter filter = new IgnoreResourceFilter(new DartIgnoreManager(), markerManager); updater = new ProjectUpdater(); filter.addDeltaListener(updater); processor.addDeltaListener(filter); processor.traverse(delta); updater.applyChanges(); project.assertPackagesRemoved(projectContainer); project.assertNoCalls(); } /** * Test removing a directory contained in a symlinked package */ public void test_traverse_package_directory_removed() throws Exception { if (!symlinkPackage(projDir)) { return; } MockFolder packages = projectContainer.getMockFolder(PACKAGES_DIRECTORY_NAME); MockFolder pkg = packages.getMockFolder("pkg1"); MockFolder folder = (MockFolder) pkg.remove("some_folder"); MockDelta delta = new MockDelta(projectContainer); delta.add(PACKAGES_DIRECTORY_NAME).add("pkg1").add(folder, REMOVED); DeltaProcessor processor = new DeltaProcessor(project); AnalysisMarkerManager markerManager = Mockito.mock(AnalysisMarkerManager.class); IgnoreResourceFilter filter = new IgnoreResourceFilter(new DartIgnoreManager(), markerManager); ProjectUpdater updater = new ProjectUpdater(); filter.addDeltaListener(updater); processor.addDeltaListener(filter); processor.traverse(delta); updater.applyChanges(); File removedDir = new File(pkg1Dir, folder.getName()); project.assertChanged(projectContainer, null, null, null, new File[] {removedDir}); project.assertNoCalls(); } /** * Test adding a file in a symlinked package */ public void test_traverse_package_file_added() throws Exception { if (!symlinkPackage(projDir)) { return; } // Create delta with a added file in pkg1 MockFolder packages = projectContainer.getMockFolder(PACKAGES_DIRECTORY_NAME); MockFolder pkg1 = packages.getMockFolder("pkg1"); MockFile file = pkg1.getMockFile("bar.dart"); MockDelta delta = new MockDelta(projectContainer); delta.add(PACKAGES_DIRECTORY_NAME).add("pkg1").add("bar.dart", ADDED); DeltaProcessor processor = new DeltaProcessor(project); AnalysisMarkerManager markerManager = Mockito.mock(AnalysisMarkerManager.class); IgnoreResourceFilter filter = new IgnoreResourceFilter(new DartIgnoreManager(), markerManager); ProjectUpdater updater = new ProjectUpdater(); filter.addDeltaListener(updater); processor.addDeltaListener(filter); processor.traverse(delta); updater.applyChanges(); File addedFile = new File(pkg1Dir, file.getName()); project.assertChanged(projectContainer, new File[] {addedFile}, null, null, null); project.assertNoCalls(); } /** * Test adding a file in a symlinked package where the "packages" directory is in a pub folder * that is not the project folder */ public void test_traverse_package_file_added2() throws Exception { projectContainer.remove(PUBSPEC_FILE_NAME); File myAppDir = new File(projDir, "myapp"); if (!symlinkPackage(myAppDir)) { return; } // Create delta with a added file in pkg1 MockFolder myApp = projectContainer.getMockFolder("myapp"); MockFolder packages = myApp.addFolder(PACKAGES_DIRECTORY_NAME); MockFolder pkg1 = packages.addFolder("pkg1"); MockFile file = pkg1.addFile("bar.dart"); MockDelta delta = new MockDelta(projectContainer); delta.add(myApp).add(PACKAGES_DIRECTORY_NAME).add("pkg1").add("bar.dart", ADDED); DeltaProcessor processor = new DeltaProcessor(project); ProjectUpdater updater = new ProjectUpdater(); processor.addDeltaListener(updater); processor.traverse(delta); updater.applyChanges(); File addedFile = new File(pkg1Dir, file.getName()); project.assertChanged(myApp, new File[] {addedFile}, null, null, null); } /** * Test changing a file in a symlinked package. * <p> * In addition, test that the delta processor correctly traverses starting with the "packages" * directory rather than the project director, similar to what will be sent to the * {@link DeltaProcessor} by the {@link WorkspaceDeltaProcessor}. */ public void test_traverse_package_file_changed() throws Exception { if (!symlinkPackage(projDir)) { return; } MockFolder packages = projectContainer.getMockFolder(PACKAGES_DIRECTORY_NAME); MockFolder pkg1 = packages.getMockFolder("pkg1"); MockFile file = pkg1.getMockFile("bar.dart"); MockDelta delta = new MockDelta(packages); delta.add("pkg1").add("bar.dart"); DeltaProcessor processor = new DeltaProcessor(project); AnalysisMarkerManager markerManager = Mockito.mock(AnalysisMarkerManager.class); IgnoreResourceFilter filter = new IgnoreResourceFilter(new DartIgnoreManager(), markerManager); ProjectUpdater updater = new ProjectUpdater(); filter.addDeltaListener(updater); processor.addDeltaListener(filter); processor.traverse(delta); updater.applyChanges(); File changedFile = new File(pkg1Dir, file.getName()); project.assertChanged(projectContainer, null, new File[] {changedFile}, null, null); project.assertNoCalls(); } /** * Test changing a file in a symlinked package in the web/packages directory and assert that no * calls are made because it is not a top level or pub directory. */ public void test_traverse_package_file_changed_inWebDir() throws Exception { if (!symlinkPackage(projDir)) { return; } MockFolder packages = projectContainer.getMockFolder("web").getMockFolder( PACKAGES_DIRECTORY_NAME); MockDelta delta = new MockDelta(packages); delta.add("pkg1").add("bar.dart"); DeltaProcessor processor = new DeltaProcessor(project); AnalysisMarkerManager markerManager = Mockito.mock(AnalysisMarkerManager.class); IgnoreResourceFilter filter = new IgnoreResourceFilter(new DartIgnoreManager(), markerManager); ProjectUpdater updater = new ProjectUpdater(); filter.addDeltaListener(updater); processor.addDeltaListener(filter); processor.traverse(delta); updater.applyChanges(); project.assertNoCalls(); } /** * Test removing a file from a symlinked package */ public void test_traverse_package_file_removed() throws Exception { if (!symlinkPackage(projDir)) { return; } MockFolder packages = projectContainer.getMockFolder(PACKAGES_DIRECTORY_NAME); MockFolder pkg = packages.getMockFolder("pkg1"); MockFile file = (MockFile) pkg.remove("bar.dart"); MockDelta delta = new MockDelta(projectContainer); delta.add(PACKAGES_DIRECTORY_NAME).add("pkg1").add(file, REMOVED); DeltaProcessor processor = new DeltaProcessor(project); AnalysisMarkerManager markerManager = Mockito.mock(AnalysisMarkerManager.class); IgnoreResourceFilter filter = new IgnoreResourceFilter(new DartIgnoreManager(), markerManager); ProjectUpdater updater = new ProjectUpdater(); filter.addDeltaListener(updater); processor.addDeltaListener(filter); processor.traverse(delta); updater.applyChanges(); File removedFile = new File(pkg1Dir, file.getName()); project.assertChanged(projectContainer, null, null, new File[] {removedFile}, null); project.assertNoCalls(); } @Override protected void setUp() throws Exception { projectContainer = TestProjects.newPubProject3(); project = new DeltaProcessorMockProject(projectContainer); projDir = FileUtilities2.createTempDir(projectContainer.getName()); pkg1Dir = FileUtilities2.createTempDir("pkg1").getCanonicalFile(); projectContainer.setLocation(new Path(projDir.getAbsolutePath())); } @Override protected void tearDown() throws Exception { FileUtilities2.deleteTempDir(); } /** * Create a symlink from the pubDir/packages/pkg1 directory to the pkg1 directory. * * @param pubDir the pub directory (not {@code null}) * @return {@code true} if symlinks can be created on this platform, else {@code false} */ private boolean symlinkPackage(File pubDir) throws IOException { if (!FileUtilities2.isSymLinkSupported()) { System.out.println("Skipping test in " + getClass().getSimpleName()); return false; } packagesDir = new File(pubDir, "packages"); assertTrue(packagesDir.mkdirs()); FileUtilities2.createSymLink(pkg1Dir, new File(packagesDir, "pkg1")); return true; } }