diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFixTest.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFixTest.java | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFixTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFixTest.java new file mode 100644 index 000000000..cc3504f58 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFixTest.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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/org/documents/epl-v10.php + * + * 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.android.ide.eclipse.adt.internal.build; + +import static com.android.SdkConstants.FD_RES; +import static com.android.SdkConstants.FD_RES_COLOR; +import static com.android.SdkConstants.FD_RES_LAYOUT; + +import com.android.ide.eclipse.adt.AdtConstants; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.AdtUtils; +import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; +import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IMarkerResolution; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.part.FileEditorInput; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class AaptQuickFixTest extends AdtProjectTest { + @Override + protected boolean testCaseNeedsUniqueProject() { + // Make a separate test project for this test such that we don't pollute code assist + // tests with our new resources + return true; + } + + public void testQuickFix1() throws Exception { + // Test adding a value into an existing file (res/values/strings.xml) + checkResourceFix("quickfix1.xml", "android:text=\"@string/firs^tstring\"", + "res/values/strings.xml"); + } + + public void testQuickFix2() throws Exception { + // Test adding a value into a new file (res/values/dimens.xml, will be created) + checkResourceFix("quickfix1.xml", "android:layout_width=\"@dimen/^testdimen\"", + "res/values/dimens.xml"); + } + + public void testQuickFix3() throws Exception { + // Test adding a file based resource (uses new file wizard machinery) + checkResourceFix("quickfix1.xml", "layout=\"@layout/^testlayout\"", + "res/layout/testlayout.xml"); + } + + public void testQuickFix4() throws Exception { + // Test adding a value into a new file (res/values/dimens.xml, will be created) + checkNamespaceFix("quickfix2.xml", "<c^olor"); + } + + private void checkResourceFix(String name, String caretLocation, String expectedNewPath) + throws Exception { + IProject project = getProject(); + IFile file = getTestDataFile(project, name, FD_RES + "/" + FD_RES_LAYOUT + "/" + name); + + // Determine the offset + final int offset = getCaretOffset(file, caretLocation); + + + String osRoot = project.getLocation().toOSString(); + List<String> errors = new ArrayList<String>(); + String fileRelativePath = file.getProjectRelativePath().toPortableString(); + String filePath = osRoot + File.separator + fileRelativePath; + // Run AaptParser such that markers are added... + // When debugging these tests, the project gets a chance to build itself so + // the real aapt errors are there. But when the test is run directly, aapt has + // not yet run. I tried waiting for the build (using the code in SampleProjectTest) + // but this had various adverse effects (exception popups from the Eclipse debugger + // etc) so instead this test just hardcodes the aapt errors that should be + // observed on quickfix1.xml. + assertEquals("Unit test is hardcoded to errors for quickfix1.xml", "quickfix1.xml", name); + errors.add(filePath + ":7: error: Error: No resource found that matches the given name" + + " (at 'text' with value '@string/firststring')."); + errors.add(filePath + ":7: error: Error: No resource found that matches the given name" + + " (at 'layout_width' with value '@dimen/testdimen')."); + errors.add(filePath + ":13: error: Error: No resource found that matches the given name" + + " (at 'layout' with value '@layout/testlayout')."); + AaptParser.parseOutput(errors, project); + + AaptQuickFix aaptQuickFix = new AaptQuickFix(); + + // Open file + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + assertNotNull(page); + IEditorPart editor = IDE.openEditor(page, file); + assertTrue(editor instanceof AndroidXmlEditor); + AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor; + final ISourceViewer viewer = layoutEditor.getStructuredSourceViewer(); + + // Test marker resolution. + IMarker[] markers = file.findMarkers(AdtConstants.MARKER_AAPT_COMPILE, true, + IResource.DEPTH_ZERO); + for (IMarker marker : markers) { + int start = marker.getAttribute(IMarker.CHAR_START, 0); + int end = marker.getAttribute(IMarker.CHAR_END, 0); + if (offset >= start && offset <= end) { + // Found the target marker. Now check the marker resolution of it. + assertTrue(aaptQuickFix.hasResolutions(marker)); + IMarkerResolution[] resolutions = aaptQuickFix.getResolutions(marker); + assertNotNull(resolutions); + assertEquals(1, resolutions.length); + IMarkerResolution resolution = resolutions[0]; + assertNotNull(resolution); + assertTrue(resolution.getLabel().contains("Create resource")); + + // Not running marker yet -- if we create the files here they already + // exist when the quick assist code runs. (The quick fix and the quick assist + // mostly share code for the implementation anyway.) + //resolution.run(marker); + break; + } + } + + // Next test quick assist. + + IQuickAssistInvocationContext invocationContext = new IQuickAssistInvocationContext() { + @Override + public int getLength() { + return 0; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public ISourceViewer getSourceViewer() { + return viewer; + } + }; + ICompletionProposal[] proposals = aaptQuickFix + .computeQuickAssistProposals(invocationContext); + assertNotNull(proposals); + assertTrue(proposals.length == 1); + ICompletionProposal proposal = proposals[0]; + + assertNotNull(proposal.getAdditionalProposalInfo()); + assertNotNull(proposal.getImage()); + assertTrue(proposal.getDisplayString().contains("Create resource")); + + IDocument document = new Document(); + String fileContent = AdtPlugin.readFile(file); + document.set(fileContent); + + // Apply quick fix + proposal.apply(document); + + IPath path = new Path(expectedNewPath); + IFile newFile = project.getFile(path); + assertNotNull(path.toPortableString(), newFile); + + // Ensure that the newly created file was opened + IEditorPart currentFile = AdtUtils.getActiveEditor(); + assertEquals(newFile.getProjectRelativePath(), + ((FileEditorInput) currentFile.getEditorInput()).getFile().getProjectRelativePath()); + + // Look up caret offset + assertTrue(currentFile != null ? currentFile.getClass().getName() : "null", + currentFile instanceof AndroidXmlEditor); + AndroidXmlEditor newEditor = (AndroidXmlEditor) currentFile; + ISourceViewer newViewer = newEditor.getStructuredSourceViewer(); + Point selectedRange = newViewer.getSelectedRange(); + + String newFileContents = AdtPlugin.readFile(newFile); + + // Insert selection markers -- [ ] for the selection range, ^ for the caret + String newFileWithCaret = addSelection(newFileContents, selectedRange); + newFileWithCaret = removeSessionData(newFileWithCaret); + + assertEqualsGolden(name, newFileWithCaret); + } + + private void checkNamespaceFix(String name, String caretLocation) + throws Exception { + IProject project = getProject(); + IFile file = getTestDataFile(project, name, FD_RES + "/" + FD_RES_COLOR + "/" + name); + + // Determine the offset + final int offset = getCaretOffset(file, caretLocation); + + String osRoot = project.getLocation().toOSString(); + List<String> errors = new ArrayList<String>(); + String fileRelativePath = file.getProjectRelativePath().toPortableString(); + String filePath = osRoot + File.separator + fileRelativePath; + assertEquals("Unit test is hardcoded to errors for quickfix2.xml", "quickfix2.xml", name); + errors.add(filePath + ":5: error: Error parsing XML: unbound prefix"); + AaptParser.parseOutput(errors, project); + + AaptQuickFix aaptQuickFix = new AaptQuickFix(); + + // Open file + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + assertNotNull(page); + IEditorPart editor = IDE.openEditor(page, file); + assertTrue(editor instanceof AndroidXmlEditor); + AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor; + final ISourceViewer viewer = layoutEditor.getStructuredSourceViewer(); + + // Test marker resolution. + IMarker[] markers = file.findMarkers(AdtConstants.MARKER_AAPT_COMPILE, true, + IResource.DEPTH_ZERO); + assertEquals(1, markers.length); + IMarker marker = markers[0]; + // Found the target marker. Now check the marker resolution of it. + assertTrue(aaptQuickFix.hasResolutions(marker)); + IMarkerResolution[] resolutions = aaptQuickFix.getResolutions(marker); + assertNotNull(resolutions); + assertEquals(1, resolutions.length); + IMarkerResolution resolution = resolutions[0]; + assertNotNull(resolution); + assertTrue(resolution.getLabel().contains("Insert namespace")); + + // Next test quick assist. + + IQuickAssistInvocationContext invocationContext = new IQuickAssistInvocationContext() { + @Override + public int getLength() { + return 0; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public ISourceViewer getSourceViewer() { + return viewer; + } + }; + ICompletionProposal[] proposals = aaptQuickFix + .computeQuickAssistProposals(invocationContext); + assertNotNull(proposals); + assertTrue(proposals.length == 1); + ICompletionProposal proposal = proposals[0]; + + assertNotNull(proposal.getAdditionalProposalInfo()); + assertNotNull(proposal.getImage()); + assertTrue(proposal.getDisplayString().contains("Insert namespace")); + + // Open the file to ensure we can get an XML model with getExistingModelForEdit: + AdtPlugin.openFile(file, null); + IEditorPart newEditor = AdtUtils.getActiveEditor(); + assertTrue(newEditor instanceof AndroidXmlEditor); + + AndroidXmlEditor xmlEditor = (AndroidXmlEditor) newEditor; + IDocument document = xmlEditor.getStructuredSourceViewer().getDocument(); + + // Apply quick fix + String before = document.get(); + proposal.apply(document); + String after = document.get(); + String diff = getDiff(before, after); + assertEqualsGolden(name, diff); + } +} |