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(AndmoreAndroidConstants.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: AndmoreAndroidPlugin.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); }
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(AndmoreAndroidConstants.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 = AndmoreAndroidPlugin.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 = AndmoreAndroidPlugin.readFile(newFile); // Insert selection markers -- [ ] for the selection range, ^ for the // caret String newFileWithCaret = addSelection(newFileContents, selectedRange); newFileWithCaret = removeSessionData(newFileWithCaret); assertEqualsGolden(name, newFileWithCaret); }
/** Performs the paste operation. */ @Override public void run() { super.run(); final String data = (String) mClipboard.getContents(TextTransfer.getInstance()); if (data != null) { mEditor.wrapEditXmlModel( new Runnable() { @Override public void run() { try { IStructuredDocument sse_doc = mEditor.getStructuredDocument(); if (sse_doc != null) { if (mUiNode.getDescriptor().hasChildren()) { // This UI Node can have children. The new XML is // inserted as the first child. if (mUiNode.getUiChildren().size() > 0) { // There's already at least one child, // so insert right before it. Node xml_node = mUiNode.getUiChildren().get(0).getXmlNode(); if (xml_node instanceof IndexedRegion) { IndexedRegion region = (IndexedRegion) xml_node; sse_doc.replace(region.getStartOffset(), 0, data); return; // we're done, no need to try the other cases } } // If there's no first XML node child. Create one by // inserting at the end of the *start* tag. Node xml_node = mUiNode.getXmlNode(); if (xml_node instanceof NodeContainer) { NodeContainer container = (NodeContainer) xml_node; IStructuredDocumentRegion start_tag = container.getStartStructuredDocumentRegion(); if (start_tag != null) { sse_doc.replace(start_tag.getEndOffset(), 0, data); return; // we're done, no need to try the other case } } } // This UI Node doesn't accept children. The new XML is inserted as the // next sibling. This also serves as a fallback if all the previous // attempts failed. However, this is not possible if the current node // has for parent a document -- an XML document can only have one root, // with no siblings. if (!(mUiNode.getUiParent() instanceof UiDocumentNode)) { Node xml_node = mUiNode.getXmlNode(); if (xml_node instanceof IndexedRegion) { IndexedRegion region = (IndexedRegion) xml_node; sse_doc.replace(region.getEndOffset(), 0, data); } } } } catch (BadLocationException e) { AndmoreAndroidPlugin.log( e, "ParseAction failed for UI Node %2$s, content '%1$s'", //$NON-NLS-1$ mUiNode.getBreadcrumbTrailDescription(true), data); } } }); } }