diff options
author | Tor Norbye <tnorbye@google.com> | 2011-03-17 12:42:40 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2011-03-17 12:42:40 -0700 |
commit | 705dc5ca1d430be514fddcdb729d52fd7110f37a (patch) | |
tree | 389c31f21142f67e579a09b5687fb5c509221e4c | |
parent | dfd85c2d3b5698bd8158eb82ff44661f4abfd34c (diff) | |
parent | bfe50d0630041bbc3e3b2b5182d18e139f2879bf (diff) | |
download | sdk-705dc5ca1d430be514fddcdb729d52fd7110f37a.zip sdk-705dc5ca1d430be514fddcdb729d52fd7110f37a.tar.gz sdk-705dc5ca1d430be514fddcdb729d52fd7110f37a.tar.bz2 |
Merge "XML code completion improvements"
60 files changed, 1384 insertions, 193 deletions
diff --git a/eclipse/dictionary.txt b/eclipse/dictionary.txt index b92ceb2..b9ccb29 100644 --- a/eclipse/dictionary.txt +++ b/eclipse/dictionary.txt @@ -205,6 +205,7 @@ tooltip tooltips traceview translucency +typo ui uncomment undescribed diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/AbsoluteLayoutRule.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/AbsoluteLayoutRule.java index c8ce3ac..47fcbd7 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/AbsoluteLayoutRule.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/AbsoluteLayoutRule.java @@ -17,7 +17,7 @@ package com.android.ide.common.layout; import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI; -import static com.android.ide.common.layout.LayoutConstants.VALUE_N_DIP; +import static com.android.ide.common.layout.LayoutConstants.VALUE_N_DP; import com.android.ide.common.api.DrawingStyle; import com.android.ide.common.api.DropFeedback; @@ -190,9 +190,9 @@ public class AbsoluteLayoutRule extends BaseLayoutRule { } newChild.setAttribute(ANDROID_URI, "layout_x", //$NON-NLS-1$ - String.format(VALUE_N_DIP, x)); + String.format(VALUE_N_DP, x)); newChild.setAttribute(ANDROID_URI, "layout_y", //$NON-NLS-1$ - String.format(VALUE_N_DIP, y)); + String.format(VALUE_N_DP, y)); addInnerElements(newChild, element, idMap); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java index a148836..092b0a5 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/LayoutConstants.java @@ -52,6 +52,7 @@ public class LayoutConstants { public static final String ATTR_TEXT = "text"; //$NON-NLS-1$ public static final String ATTR_ID = "id"; //$NON-NLS-1$ + public static final String ATTR_STYLE = "style"; //$NON-NLS-1$ public static final String ATTR_HANDLE = "handle"; //$NON-NLS-1$ public static final String ATTR_CONTENT = "content"; //$NON-NLS-1$ public static final String ATTR_CHECKED = "checked"; //$NON-NLS-1$ @@ -98,7 +99,7 @@ public class LayoutConstants { public static final String VALUE_FILL_PARENT = "fill_parent"; //$NON-NLS-1$ public static final String VALUE_TRUE = "true"; //$NON-NLS-1$ public static final String VALUE_FALSE= "false"; //$NON-NLS-1$ - public static final String VALUE_N_DIP = "%ddip"; //$NON-NLS-1$ + public static final String VALUE_N_DP = "%ddp"; //$NON-NLS-1$ public static final String VALUE_CENTER_VERTICAL = "centerVertical"; //$NON-NLS-1$ public static final String VALUE_CENTER_IN_PARENT = "centerInParent"; //$NON-NLS-1$ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java index 9bc09ec..61c34bf 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java @@ -16,6 +16,10 @@ package com.android.ide.eclipse.adt.internal.editors; +import static com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor.ATTRIBUTE_ICON_FILENAME; + +import com.android.ide.common.api.IAttributeInfo; +import com.android.ide.common.api.IAttributeInfo.Format; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; @@ -32,10 +36,12 @@ import com.android.ide.eclipse.adt.internal.editors.uimodel.UiFlagAttributeNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; import com.android.sdklib.SdkConstants; +import com.android.util.Pair; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.contentassist.CompletionProposal; @@ -50,12 +56,15 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; +import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.regex.Pattern; /** @@ -148,29 +157,51 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { return null; } + boolean isNew = true; + int replaceLength = 0; if (currentNode.getNodeType() == Node.ELEMENT_NODE) { parent = currentNode.getNodeName(); - if (wordPrefix.equals(parent)) { + // We're not editing the current node name, so we might be editing its + // attributes instead... + AttribInfo info = parseAttributeInfo(viewer, offset); + if (info != null) { + isAttribute = true; + // We're editing attributes in an element node (either the attributes' names + // or their values). + choices = getChoicesForAttribute(parent, currentNode, currentUiNode, info); + + if (info.isInValue) { + // Note - this must be done before the prefix correction below since + // otherwise, when the prefix gets cleared out (for a flag list) we + // end up with a wrong count for the prefix length + Element element = (Element) currentNode; + String attribute = element.getAttribute(info.name); + if (attribute != null) { // Eclipse DOM bug + replaceLength = attribute.length() - wordPrefix.length(); + if (info.needTag != 0) { + replaceLength += 2; + } + } + } else { + replaceLength = info.name.length() - wordPrefix.length(); + } + + if (info.correctedPrefix != null) { + wordPrefix = info.correctedPrefix; + } + needTag = info.needTag; + isNew = info.name.length() == 0; + } else if (parent.startsWith(wordPrefix)) { // We are still editing the element's tag name, not the attributes // (the element's tag name may not even be complete) isElement = true; choices = getChoicesForElement(parent, currentNode); - } else { - // We're not editing the current node name, so we might be editing its - // attributes instead... - isAttribute = true; - AttribInfo info = parseAttributeInfo(viewer, offset); - if (info != null) { - // We're editing attributes in an element node (either the attributes' names - // or their values). - choices = getChoicesForAttribute(parent, currentNode, currentUiNode, info); - - if (info.correctedPrefix != null) { - wordPrefix = info.correctedPrefix; - } - needTag = info.needTag; + replaceLength = parent.length() - wordPrefix.length(); + if (wordPrefix.length() == 0) { + replaceLength = 0; // Only do this if on < } + isNew = replaceLength == 0; } } else if (currentNode.getNodeType() == Node.TEXT_NODE) { isElement = true; @@ -201,7 +232,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { } return computeProposals(offset, currentNode, choices, wordPrefix, needTag, - isAttribute, selectionLength); + isAttribute, isNew, selectionLength + replaceLength); } /** @@ -345,24 +376,31 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { // A "flag" can consist of several values separated by "or" (|). // If the correct prefix contains such a pipe character, we change // it so that only the currently edited value is completed. - pos = value.indexOf('|'); + pos = value.lastIndexOf('|'); if (pos >= 0) { attrInfo.correctedPrefix = value = value.substring(pos + 1); attrInfo.needTag = 0; } } - } - if (choices == null && value.startsWith("@")) { //$NON-NLS-1$ - // Special case: If the attribute value looks like a reference to a - // resource, offer to complete it, since in many cases our metadata - // does not correctly state whether a resource value is allowed. We don't - // offer these for an empty completion context, but if the user has - // actually typed "@", in that case list resource matches. - // For example, for android:minHeight this makes completion on @dimen/ - // possible. - choices = UiResourceAttributeNode.computeResourceStringMatches(currentUiNode, - value); + // Should we do suffix completion on dimension units etc? + choices = completeSuffix(choices, value, currAttrNode); + + // Check to see if the user is attempting resource completion + AttributeDescriptor attributeDescriptor = currAttrNode.getDescriptor(); + IAttributeInfo attributeInfo = attributeDescriptor.getAttributeInfo(); + if (value.startsWith("@") //$NON-NLS-1$ + && !Format.REFERENCE.in(attributeInfo.getFormats())) { + // Special case: If the attribute value looks like a reference to a + // resource, offer to complete it, since in many cases our metadata + // does not correctly state whether a resource value is allowed. We don't + // offer these for an empty completion context, but if the user has + // actually typed "@", in that case list resource matches. + // For example, for android:minHeight this makes completion on @dimen/ + // possible. + choices = UiResourceAttributeNode.computeResourceStringMatches( + currentUiNode, attributeDescriptor, value); + } } } @@ -436,14 +474,16 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { * - AttributeDescriptor: a possible attribute descriptor which XML name should be completed. * - String: string values to display as-is to the user. Typically those are possible * values for a given attribute. + * - Pair of Strings: the first value is the keyword to insert, and the second value + * is the tooltip/help for the value to be displayed in the documentation popup. * * @return The ICompletionProposal[] to display to the user. */ private ICompletionProposal[] computeProposals(int offset, Node currentNode, - Object[] choices, String wordPrefix, char need_tag, - boolean is_attribute, int selectionLength) { - ArrayList<CompletionProposal> proposals = new ArrayList<CompletionProposal>(); - HashMap<String, String> nsUriMap = new HashMap<String, String>(); + Object[] choices, String wordPrefix, char needTag, + boolean isAttribute, boolean isNew, int replaceLength) { + List<CompletionProposal> proposals = new ArrayList<CompletionProposal>(); + Map<String, String> nsUriMap = new HashMap<String, String>(); for (Object choice : choices) { String keyword = null; @@ -481,6 +521,17 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { } else if (choice instanceof String) { keyword = (String) choice; + if (isAttribute) { + icon = IconFactory.getInstance().getIcon(ATTRIBUTE_ICON_FILENAME); + } + } else if (choice instanceof Pair<?, ?>) { + @SuppressWarnings("unchecked") + Pair<String, String> pair = (Pair<String, String>) choice; + keyword = pair.getFirst(); + tooltip = pair.getSecond(); + if (isAttribute) { + icon = IconFactory.getInstance().getIcon(ATTRIBUTE_ICON_FILENAME); + } } else { continue; // discard unknown choice } @@ -493,18 +544,18 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { if (nsPrefix != null) { keyword = nsPrefix + keyword; } - String end_tag = ""; //$NON-NLS-1$ - if (need_tag != 0) { - if (need_tag == '"') { - keyword = need_tag + keyword; - end_tag = String.valueOf(need_tag); - } else if (need_tag == '<') { + String endTag = ""; //$NON-NLS-1$ + if (needTag != 0) { + if (needTag == '"') { + keyword = needTag + keyword; + endTag = String.valueOf(needTag); + } else if (needTag == '<') { if (elementCanHaveChildren(choice)) { - end_tag = String.format("></%1$s>", keyword); //$NON-NLS-1$ - keyword = need_tag + keyword; + endTag = String.format("></%1$s>", keyword); //$NON-NLS-1$ + keyword = needTag + keyword; } else { - keyword = need_tag + keyword; - end_tag = "/>"; //$NON-NLS-1$ + keyword = needTag + keyword; + endTag = "/>"; //$NON-NLS-1$ } } } @@ -513,13 +564,13 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { // For attributes, automatically insert ns:attribute="" and place the cursor // inside the quotes. - if (choice instanceof AttributeDescriptor) { + if (choice instanceof AttributeDescriptor && isNew) { // Special case for attributes: insert ="" stuff and locate caret inside "" String suffix = "=\"\""; //$NON-NLS-1$ proposal = new CompletionProposal( keyword + suffix , // String replacementString offset - wordPrefix.length(), // int replacementOffset - wordPrefix.length() + selectionLength, // int replacementLength + wordPrefix.length() + replaceLength, // int replacementLength keyword.length() + suffix.length() - 1, // cursorPosition icon, // Image image keyword, // displayString - don't include ="" @@ -527,11 +578,16 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { tooltip // String additionalProposalInfo ); } else { + int cursorPosition = keyword.length(); + if (choice instanceof ElementDescriptor && isNew) { + endTag = ' ' + endTag; + cursorPosition += 1; + } proposal = new CompletionProposal( - keyword + end_tag, // String replacementString + keyword + endTag, // String replacementString offset - wordPrefix.length(), // int replacementOffset - wordPrefix.length() + selectionLength, // int replacementLength - keyword.length(), // int cursorPosition (rel. to rplcmntOffset) + wordPrefix.length() + replaceLength, // int replacementLength + cursorPosition, // int cursorPosition (rel. to rplcmntOffset) icon, // Image image null, // String displayString null, // IContextInformation contextInformation @@ -579,7 +635,8 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { * or if one of the attributes is a TextValueDescriptor. * * @param descriptor An ElementDescriptor or an AttributeDescriptor - * @return True if the descriptor is an ElementDescriptor that can have children or a text value + * @return True if the descriptor is an ElementDescriptor that can have children or a text + * value */ private boolean elementCanHaveChildren(Object descriptor) { if (descriptor instanceof ElementDescriptor) { @@ -587,8 +644,8 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { if (desc.hasChildren()) { return true; } - for (AttributeDescriptor attr_desc : desc.getAttributes()) { - if (attr_desc instanceof TextValueDescriptor) { + for (AttributeDescriptor attrDesc : desc.getAttributes()) { + if (attrDesc instanceof TextValueDescriptor) { return true; } } @@ -729,14 +786,22 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { */ private AttribInfo parseAttributeInfo(ITextViewer viewer, int offset) { AttribInfo info = new AttribInfo(); + int originalOffset = offset; IDocument document = viewer.getDocument(); int n = document.getLength(); if (offset <= n) { try { + // Look to the right to make sure we aren't sitting on the boundary of the + // beginning of a new element with whitespace before it + if (offset < n && document.getChar(offset) == '<') { + return null; + } + n = offset; for (;offset > 0; --offset) { char ch = document.getChar(offset - 1); + if (ch == '>') break; if (ch == '<') break; } @@ -780,6 +845,22 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { if (pos_equal == -1) { info.isInValue = false; info.name = text.trim(); + + // info.name is currently just the prefix of the attribute name. + // Look at the text buffer to find the complete name (since we need + // to know its bounds in order to replace it when a different attribute + // that matches this prefix is chosen) + IRegion lineInfo = document.getLineInformationOfOffset(originalOffset); + String line = document.get(lineInfo.getOffset(), lineInfo.getLength()); + int nameStart = originalOffset - lineInfo.getOffset(); + for (int nameEnd = nameStart; nameEnd < line.length(); nameEnd++) { + char c = line.charAt(nameEnd); + if (!(Character.isLetter(c) || c == ':' || c == '_')) { + String nameSuffix = line.substring(nameStart, nameEnd); + info.name = text.trim() + nameSuffix; + break; + } + } } else { info.isInValue = true; info.name = text.substring(0, pos_equal).trim(); @@ -831,7 +912,8 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { if (page != null) { IEditorPart editor = page.getActiveEditor(); if (editor instanceof AndroidXmlEditor) { - ISourceViewer ssviewer = ((AndroidXmlEditor) editor).getStructuredSourceViewer(); + ISourceViewer ssviewer = + ((AndroidXmlEditor) editor).getStructuredSourceViewer(); if (ssviewer == viewer) { return (AndroidXmlEditor) editor; } @@ -842,6 +924,132 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { return null; } + /** + * Fixed list of dimension units, along with user documentation, for use by + * {@link #completeSuffix}. + */ + private static final String[] sDimensionUnits = new String[] { + "dp", //$NON-NLS-1$ + "<b>Density-independent Pixels</b> - an abstract unit that is based on the physical " + + "density of the screen.", + + "sp", //$NON-NLS-1$ + "<b>Scale-independent Pixels</b> - this is like the dp unit, but it is also scaled by " + + "the user's font size preference.", + + "pt", //$NON-NLS-1$ + "<b>Points</b> - 1/72 of an inch based on the physical size of the screen.", + + "mm", //$NON-NLS-1$ + "<b>Millimeters</b> - based on the physical size of the screen.", + + "in", //$NON-NLS-1$ + "<b>Inches</b> - based on the physical size of the screen.", + + "px", //$NON-NLS-1$ + "<b>Pixels</b> - corresponds to actual pixels on the screen. Not recommended.", + }; + + /** + * Fixed list of fractional units, along with user documentation, for use by + * {@link #completeSuffix} + */ + private static final String[] sFractionUnits = new String[] { + "%", //$NON-NLS-1$ + "<b>Fraction</b> - a percentage of the base size", + + "%p", //$NON-NLS-1$ + "<b>Fraction</b> - a percentage relative to parent container", + }; + /** + * Completes suffixes for applicable types (like dimensions and fractions) such that + * after a dimension number you get completion on unit types like "px". + */ + private Object[] completeSuffix(Object[] choices, String value, UiAttributeNode currAttrNode) { + IAttributeInfo attributeInfo = currAttrNode.getDescriptor().getAttributeInfo(); + Format[] formats = attributeInfo.getFormats(); + List<Object> suffixes = new ArrayList<Object>(); + + if (value.length() > 0 && Character.isDigit(value.charAt(0))) { + boolean hasDimension = Format.DIMENSION.in(formats); + boolean hasFraction = Format.FRACTION.in(formats); + + if (hasDimension || hasFraction) { + // Split up the value into a numeric part (the prefix) and the + // unit part (the suffix) + int suffixBegin = 0; + for (; suffixBegin < value.length(); suffixBegin++) { + if (!Character.isDigit(value.charAt(suffixBegin))) { + break; + } + } + String number = value.substring(0, suffixBegin); + String suffix = value.substring(suffixBegin); + + // Add in the matching dimension and/or fraction units, if any + if (hasDimension) { + // Each item has two entries in the array of strings: the first odd numbered + // ones are the unit names and the second even numbered ones are the + // corresponding descriptions. + for (int i = 0; i < sDimensionUnits.length; i += 2) { + String unit = sDimensionUnits[i]; + if (startsWith(unit, suffix)) { + String description = sDimensionUnits[i + 1]; + suffixes.add(Pair.of(number + unit, description)); + } + } + // Allow "dip" completion but don't offer it ("dp" is preferred) + if (suffix.startsWith("di") || suffix.startsWith("dip")) { //$NON-NLS-1$ //$NON-NLS-2$ + suffixes.add(Pair.of(number + "dip", "Alternative name for \"dp\"")); //$NON-NLS-1$ + } + } + if (hasFraction) { + for (int i = 0; i < sFractionUnits.length; i += 2) { + String unit = sFractionUnits[i]; + if (startsWith(unit, suffix)) { + String description = sFractionUnits[i + 1]; + suffixes.add(Pair.of(number + unit, description)); + } + } + } + } + } + + boolean hasFlag = Format.FLAG.in(formats); + if (hasFlag) { + boolean isDone = false; + String[] flagValues = attributeInfo.getFlagValues(); + for (String flagValue : flagValues) { + if (flagValue.equals(value)) { + isDone = true; + break; + } + } + if (isDone) { + // Add in all the new values with a separator of | + String currentValue = currAttrNode.getCurrentValue(); + for (String flagValue : flagValues) { + if (currentValue == null || !currentValue.contains(flagValue)) { + suffixes.add(value + '|' + flagValue); + } + } + } + } + + if (suffixes.size() > 0) { + // Merge previously added choices (from attribute enums etc) with the new matches + List<Object> all = new ArrayList<Object>(); + if (choices != null) { + for (Object s : choices) { + all.add(s); + } + } + all.addAll(suffixes); + choices = all.toArray(); + } + + return choices; + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java index 38d8844..258db03 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java @@ -18,23 +18,28 @@ package com.android.ide.eclipse.adt.internal.editors; import org.eclipse.jface.text.IAutoEditStrategy; -import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; import org.eclipse.jface.text.formatter.IContentFormatter; import org.eclipse.jface.text.source.ISourceViewer; -import org.eclipse.jface.viewers.IInputProvider; import org.eclipse.wst.sse.core.text.IStructuredPartitions; import org.eclipse.wst.xml.core.text.IXMLPartitions; import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML; +import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor; import java.util.ArrayList; +import java.util.List; import java.util.Map; /** * Base Source Viewer Configuration for Android resources. */ +@SuppressWarnings("restriction") // XMLContentAssistProcessor public class AndroidSourceViewerConfig extends StructuredTextViewerConfigurationXML { /** Content Assist Processor to use for all handled partitions. */ @@ -67,17 +72,6 @@ public class AndroidSourceViewerConfig extends StructuredTextViewerConfiguration if (partitionType == IStructuredPartitions.UNKNOWN_PARTITION || partitionType == IStructuredPartitions.DEFAULT_PARTITION || partitionType == IXMLPartitions.XML_DEFAULT) { - if (sourceViewer instanceof IInputProvider) { - IInputProvider input = (IInputProvider) sourceViewer; - Object a = input.getInput(); - if (a != null) - a.toString(); - } - - IDocument doc = sourceViewer.getDocument(); - if (doc != null) - doc.toString(); - processors.add(mProcessor); } @@ -85,7 +79,13 @@ public class AndroidSourceViewerConfig extends StructuredTextViewerConfiguration partitionType); if (others != null && others.length > 0) { for (IContentAssistProcessor p : others) { - processors.add(p); + // Builtin Eclipse WTP code completion assistant? If so, + // wrap it with our own filter which hides some unwanted completions. + if (p instanceof XMLContentAssistProcessor) { + processors.add(new FilteringContentAssistProcessor(p)); + } else { + processors.add(p); + } } } @@ -125,4 +125,69 @@ public class AndroidSourceViewerConfig extends StructuredTextViewerConfiguration return targets; } + /** + * A delegating {@link IContentAssistProcessor} whose purpose is to filter out some + * default Eclipse XML completions which are distracting in Android XML files + */ + private class FilteringContentAssistProcessor implements IContentAssistProcessor { + private IContentAssistProcessor mDelegate; + + public FilteringContentAssistProcessor(IContentAssistProcessor delegate) { + super(); + mDelegate = delegate; + } + + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { + ICompletionProposal[] result = mDelegate.computeCompletionProposals(viewer, offset); + if (result == null) { + return null; + } + + List<ICompletionProposal> proposals = + new ArrayList<ICompletionProposal>(result.length); + for (ICompletionProposal proposal : result) { + String replacement = proposal.getDisplayString(); + if (replacement.charAt(0) == '"' && + replacement.charAt(replacement.length() - 1) == '"') { + // Filter out attribute values. In Android XML files (where there is no DTD + // etc) the default Eclipse XML code completion simply provides the + // existing value as a completion. This is often misleading, since if you + // for example have a typo, completion will show your current (wrong) + // value as a valid completion. + } else if (replacement.contains("Namespace") //$NON-NLS-1$ + || replacement.contains("Schema")) { //$NON-NLS-1$ + // Eclipse adds in a number of namespace and schema related completions which + // are not usually applicable in our files. + } else { + proposals.add(proposal); + } + } + + if (proposals.size() == result.length) { + return result; + } else { + return proposals.toArray(new ICompletionProposal[proposals.size()]); + } + } + + public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) { + return mDelegate.computeContextInformation(viewer, offset); + } + + public char[] getCompletionProposalAutoActivationCharacters() { + return mDelegate.getCompletionProposalAutoActivationCharacters(); + } + + public char[] getContextInformationAutoActivationCharacters() { + return mDelegate.getContextInformationAutoActivationCharacters(); + } + + public IContextInformationValidator getContextInformationValidator() { + return mDelegate.getContextInformationValidator(); + } + + public String getErrorMessage() { + return mDelegate.getErrorMessage(); + } + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java index 1cf11e4..e6df2ca 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java @@ -35,7 +35,7 @@ import org.eclipse.swt.graphics.Image; * the correct UiAttributeNode-derived class. */ public abstract class AttributeDescriptor { - private static final String ATTRIBUTE_ICON_FILENAME = "attribute"; //$NON-NLS-1$ + public static final String ATTRIBUTE_ICON_FILENAME = "attribute"; //$NON-NLS-1$ private final String mXmlLocalName; private final String mNsUri; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java index 4b313f6..d55db31 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java @@ -16,16 +16,18 @@ package com.android.ide.eclipse.adt.internal.editors.layout; +import com.android.annotations.VisibleForTesting; import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; /** * Content Assist Processor for /res/layout XML files */ -class LayoutContentAssist extends AndroidContentAssist { +@VisibleForTesting +public final class LayoutContentAssist extends AndroidContentAssist { /** - * Constructor for LayoutContentAssist + * Constructor for LayoutContentAssist */ public LayoutContentAssist() { super(AndroidTargetData.DESCRIPTOR_LAYOUT); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java index 6e85412..193c3c0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RelativeLayoutConversionHelper.java @@ -57,7 +57,7 @@ import static com.android.ide.common.layout.LayoutConstants.LINEAR_LAYOUT; import static com.android.ide.common.layout.LayoutConstants.NEW_ID_PREFIX; import static com.android.ide.common.layout.LayoutConstants.RELATIVE_LAYOUT; import static com.android.ide.common.layout.LayoutConstants.VALUE_FALSE; -import static com.android.ide.common.layout.LayoutConstants.VALUE_N_DIP; +import static com.android.ide.common.layout.LayoutConstants.VALUE_N_DP; import static com.android.ide.common.layout.LayoutConstants.VALUE_TRUE; import static com.android.ide.common.layout.LayoutConstants.VALUE_VERTICAL; import static com.android.ide.common.layout.LayoutConstants.VALUE_WRAP_CONTENT; @@ -911,7 +911,7 @@ class RelativeLayoutConversionHelper { view.addHorizConstraint(attachLeftProperty, attachLeftValue); if (marginLeft > 0) { view.addHorizConstraint(ATTR_LAYOUT_MARGIN_LEFT, - String.format(VALUE_N_DIP, marginLeft)); + String.format(VALUE_N_DP, marginLeft)); marginLeft = 0; } } else { @@ -965,7 +965,7 @@ class RelativeLayoutConversionHelper { view.addVerticalConstraint(attachTopProperty, attachTopValue); if (marginTop > 0) { view.addVerticalConstraint(ATTR_LAYOUT_MARGIN_TOP, - String.format(VALUE_N_DIP, marginTop)); + String.format(VALUE_N_DP, marginTop)); marginTop = 0; } } else { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java index 349048f..1c92309 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java @@ -16,16 +16,18 @@ package com.android.ide.eclipse.adt.internal.editors.manifest; +import com.android.annotations.VisibleForTesting; import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist; import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData; /** * Content Assist Processor for AndroidManifest.xml */ -final class ManifestContentAssist extends AndroidContentAssist { +@VisibleForTesting +public final class ManifestContentAssist extends AndroidContentAssist { /** - * Constructor for ManifestContentAssist + * Constructor for ManifestContentAssist */ public ManifestContentAssist() { super(AndroidTargetData.DESCRIPTOR_MANIFEST); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java index 9032b46..c0ca837 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java @@ -16,12 +16,17 @@ package com.android.ide.eclipse.adt.internal.editors.uimodel; +import static com.android.ide.common.layout.LayoutConstants.ATTR_ID; +import static com.android.ide.common.layout.LayoutConstants.ATTR_STYLE; import static com.android.ide.eclipse.adt.AdtConstants.ANDROID_PKG; +import com.android.ide.common.api.IAttributeInfo; +import com.android.ide.common.api.IAttributeInfo.Format; import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils; import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor; +import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors; import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceItem; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; @@ -49,7 +54,10 @@ import org.eclipse.ui.forms.widgets.TableWrapData; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.EnumSet; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -63,6 +71,8 @@ import java.util.regex.Pattern; * See {@link UiTextAttributeNode} for more information. */ public class UiResourceAttributeNode extends UiTextAttributeNode { + /** The resource prefix @android: */ + private static final String ANDROID_RESOURCE_PREFIX = '@' + ANDROID_PKG + ':'; private ResourceType mType; @@ -198,10 +208,11 @@ public class UiResourceAttributeNode extends UiTextAttributeNode { */ @Override public String[] getPossibleValues(String prefix) { - return computeResourceStringMatches(getUiParent(), prefix); + return computeResourceStringMatches(getUiParent(), getDescriptor(), prefix); } - public static String[] computeResourceStringMatches(UiElementNode uiNode, String prefix) { + public static String[] computeResourceStringMatches(UiElementNode uiNode, + AttributeDescriptor attributeDescriptor, String prefix) { ResourceRepository repository = null; boolean isSystem = false; AndroidXmlEditor editor = uiNode.getEditor(); @@ -236,7 +247,7 @@ public class UiResourceAttributeNode extends UiTextAttributeNode { } // Now collect results - ArrayList<String> results = new ArrayList<String>(); + List<String> results = new ArrayList<String>(); if (typeName == null) { // This prefix does not have a / in it, so the resource string is either empty @@ -245,13 +256,13 @@ public class UiResourceAttributeNode extends UiTextAttributeNode { for (ResourceType resType : resTypes) { if (isSystem) { - results.add("@" + ANDROID_PKG + ':' + resType.getName() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ + results.add(ANDROID_RESOURCE_PREFIX + resType.getName() + '/'); } else { - results.add("@" + resType.getName() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ + results.add('@' + resType.getName() + '/'); } if (resType == ResourceType.ID) { // Also offer the + version to create an id from scratch - results.add("@+" + resType.getName() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ + results.add("@+" + resType.getName() + '/'); //$NON-NLS-1$ } } @@ -259,7 +270,7 @@ public class UiResourceAttributeNode extends UiTextAttributeNode { // "@an" we offer to complete it. if (prefix == null || ANDROID_PKG.regionMatches(0, prefix, 1, prefix.length() - 1)) { - results.add('@' + ANDROID_PKG + ':'); + results.add(ANDROID_RESOURCE_PREFIX); } } else if (repository != null) { // We have a style name and a repository. Find all resources that match this @@ -286,6 +297,94 @@ public class UiResourceAttributeNode extends UiTextAttributeNode { } } + sortAttributeChoices(attributeDescriptor, results); + return results.toArray(new String[results.size()]); } + + /** + * Attempts to sort the attribute values to bubble up the most likely choices to + * the top. + * <p> + * For example, if you are editing a style attribute, it's likely that among the + * resource values you would rather see @style or @android than @string. + */ + private static void sortAttributeChoices(AttributeDescriptor descriptor, + List<String> choices) { + final IAttributeInfo attributeInfo = descriptor.getAttributeInfo(); + Collections.sort(choices, new Comparator<String>() { + public int compare(String s1, String s2) { + int compare = score(attributeInfo, s1) - score(attributeInfo, s2); + if (compare == 0) { + // Sort alphabetically as a fallback + compare = s1.compareTo(s2); + } + return compare; + } + }); + } + + /** Compute a suitable sorting score for the given */ + private static final int score(IAttributeInfo attributeInfo, String value) { + if (value.equals(ANDROID_RESOURCE_PREFIX)) { + return -1; + } + + for (Format format : attributeInfo.getFormats()) { + String type = null; + switch (format) { + case BOOLEAN: + type = "bool"; //$NON-NLS-1$ + break; + case COLOR: + type = "color"; //$NON-NLS-1$ + break; + case DIMENSION: + type = "dimen"; //$NON-NLS-1$ + break; + case INTEGER: + type = "integer"; //$NON-NLS-1$ + break; + case STRING: + type = "string"; //$NON-NLS-1$ + break; + // default: REFERENCE, FLAG, ENUM, etc - don't have type info about individual + // elements to help make a decision + } + + if (type != null) { + if (value.startsWith('@' + type + '/')) { + return -2; + } + + if (value.startsWith(ANDROID_RESOURCE_PREFIX + type + '/')) { + return -2; + } + } + } + + // Handle a few more cases not covered by the Format metadata check + String type = null; + + String attribute = attributeInfo.getName(); + if (attribute.equals(ATTR_ID)) { + type = "id"; //$NON-NLS-1$ + } else if (attribute.equals(ATTR_STYLE)) { + type = "style"; //$NON-NLS-1$ + } else if (attribute.equals(LayoutDescriptors.ATTR_LAYOUT)) { + type = "layout"; //$NON-NLS-1$ + } + + if (type != null) { + if (value.startsWith('@' + type + '/')) { + return -2; + } + + if (value.startsWith(ANDROID_RESOURCE_PREFIX + type + '/')) { + return -2; + } + } + + return 0; + } } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java new file mode 100644 index 0000000..38e3bfd --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java @@ -0,0 +1,376 @@ +/* + * 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.editors; + +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.editors.layout.LayoutContentAssist; +import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest; +import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestContentAssist; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; + +public class AndroidContentAssistTest extends AdtProjectTest { + private static final String CARET = "^"; //$NON-NLS-1$ + + public void testStartsWith() { + assertTrue(AndroidContentAssist.startsWith("", "")); + assertTrue(AndroidContentAssist.startsWith("a", "")); + assertTrue(AndroidContentAssist.startsWith("A", "")); + assertTrue(AndroidContentAssist.startsWith("A", "a")); + assertTrue(AndroidContentAssist.startsWith("A", "A")); + assertTrue(AndroidContentAssist.startsWith("Ab", "a")); + assertTrue(AndroidContentAssist.startsWith("ab", "A")); + assertTrue(AndroidContentAssist.startsWith("ab", "AB")); + assertFalse(AndroidContentAssist.startsWith("ab", "ABc")); + assertFalse(AndroidContentAssist.startsWith("", "ABc")); + } + + public void testCompletion1() throws Exception { + // Change attribute name completion + checkLayoutCompletion("completion1.xml", "layout_w^idth=\"fill_parent\""); + } + + public void testCompletion2() throws Exception { + // Check attribute value completion for enum + checkLayoutCompletion("completion1.xml", "layout_width=\"^fill_parent\""); + } + + public void testCompletion3() throws Exception { + // Check attribute value completion for enum with a prefix + checkLayoutCompletion("completion1.xml", "layout_width=\"fi^ll_parent\""); + } + + public void testCompletion4() throws Exception { + // Check attribute value completion on units + checkLayoutCompletion("completion1.xml", "marginBottom=\"50^\""); + } + + public void testCompletion5() throws Exception { + // Check attribute value completion on units with prefix + checkLayoutCompletion("completion1.xml", "layout_marginLeft=\"50d^p\""); + } + + public void testCompletion6() throws Exception { + // Check resource sorting - "style" should bubble to the top for a style attribute + checkLayoutCompletion("completion1.xml", "style=\"@android:^style/Widget.Button\""); + } + + public void testCompletion7a() throws Exception { + // Check flags (multiple values inside a single XML value, separated by | - where + // the prefix is reset as soon as you pass each | ) + checkLayoutCompletion("completion1.xml", "android:gravity=\"l^eft|bottom\""); + } + + public void testCompletion7b() throws Exception { + checkLayoutCompletion("completion1.xml", "android:gravity=\"left|b^ottom\""); + } + + public void testCompletion8() throws Exception { + // Test completion right at the "=" sign; this will be taken to be the last + // character of the attribute name (the caret is between the last char and before + // the = characters), so it should match a single attribute + checkLayoutCompletion("completion1.xml", "layout_width^=\"fill_parent\""); + } + + public void testCompletion9() throws Exception { + // Test completion right after the "=" sign; this will be taken to be the beginning + // of the attribute value, but all values will also include a leading quote + checkLayoutCompletion("completion1.xml", "layout_width=^\"fill_parent\""); + } + + public void testCompletion10() throws Exception { + // Test completion of element names + checkLayoutCompletion("completion1.xml", "<T^extView"); + } + + public void testCompletion11() throws Exception { + // Test completion of element names at the outside of the <. This should include + // all the elements too (along with the leading <). + checkLayoutCompletion("completion1.xml", "^<TextView"); + } + + public void testCompletion12() throws Exception { + // Test completion of element names inside a nested XML; ensure that this will + // correctly compute element names, not previous attribute + checkLayoutCompletion("completion1.xml", "btn_default\">^</FrameLayout>"); + } + + public void testCompletion13a() throws Exception { + checkLayoutCompletion("completion2.xml", "gravity=\"left|bottom|^cen"); + } + + public void testCompletion13b() throws Exception { + checkLayoutCompletion("completion2.xml", "gravity=\"left|bottom|cen^"); + } + + public void testCompletion13c() throws Exception { + checkLayoutCompletion("completion2.xml", "gravity=\"left|bottom^|cen"); + } + + public void testCompletion14() throws Exception { + // Test completion of permissions + checkManifestCompletion("manifest.xml", "android.permission.ACC^ESS_NETWORK_STATE"); + } + + public void testCompletion15() throws Exception { + // Test completion of intents + checkManifestCompletion("manifest.xml", "android.intent.category.L^AUNCHER"); + } + + public void testCompletion16() throws Exception { + // Test completion of top level elements + checkManifestCompletion("manifest.xml", "<^application android:i"); + } + + public void testCompletion17() throws Exception { + // Test completion of attributes on the manifest element + checkManifestCompletion("manifest.xml", "^android:versionCode=\"1\""); + } + + public void testCompletion18() throws Exception { + // Test completion of attributes on the manifest element + checkManifestCompletion("manifest.xml", + "<activity android:^name=\".TestActivity\""); + } + + // ---- Test *applying* code completion ---- + + // The following tests check -applying- a specific code completion + // match - this verifies that the document is updated correctly, the + // caret is moved appropriately, etc. + + public void testApplyCompletion1() throws Exception { + // Change attribute name completion + checkApplyLayoutCompletion("completion1.xml", "layout_w^idth=\"fill_parent\"", + "android:layout_weight"); + } + + public void testApplyCompletion2() throws Exception { + // Check attribute value completion for enum + checkApplyLayoutCompletion("completion1.xml", "layout_width=\"^fill_parent\"", + "match_parent"); + } + + public void testApplyCompletion3() throws Exception { + // Check attribute value completion for enum with a prefix + checkApplyLayoutCompletion("completion1.xml", "layout_width=\"fi^ll_parent\"", + "fill_parent"); + } + + public void testApplyCompletion4() throws Exception { + // Check attribute value completion on units + checkApplyLayoutCompletion("completion1.xml", "marginBottom=\"50^\"", "50mm"); + } + + public void testApplyCompletion5() throws Exception { + // Check attribute value completion on units with prefix + checkApplyLayoutCompletion("completion1.xml", "layout_marginLeft=\"50d^p\"", "50dp"); + } + + public void testApplyCompletion6() throws Exception { + // Check resource sorting - "style" should bubble to the top for a style attribute + checkApplyLayoutCompletion("completion1.xml", "style=\"@android:^style/Widget.Button\"", + "@android:drawable/"); + } + + public void testApplyCompletion7a() throws Exception { + // Check flags (multiple values inside a single XML value, separated by | - where + // the prefix is reset as soon as you pass each | ) + checkApplyLayoutCompletion("completion1.xml", "android:gravity=\"l^eft|bottom\"", + "left"); + // NOTE - this will replace all flag values with the newly selected value. + // That may not be the best behavior - perhaps we should only replace one portion + // of the value. + } + + public void testApplyCompletion7b() throws Exception { + checkApplyLayoutCompletion("completion1.xml", "android:gravity=\"left|b^ottom\"", + "bottom"); + // NOTE - this will replace all flag values with the newly selected value. + // That may not be the best behavior - perhaps we should only replace one portion + // of the value. + } + + public void testApplyCompletion8() throws Exception { + // Test completion right at the "=" sign; this will be taken to be the last + // character of the attribute name (the caret is between the last char and before + // the = characters), so it should match a single attribute + checkApplyLayoutCompletion("completion1.xml", "layout_width^=\"fill_parent\"", + "android:layout_width"); + } + + public void testApplyCompletion9() throws Exception { + // Test completion right after the "=" sign; this will be taken to be the beginning + // of the attribute value, but all values will also include a leading quote + checkApplyLayoutCompletion("completion1.xml", "layout_width=^\"fill_parent\"", + "\"wrap_content\""); + } + + public void testApplyCompletion10() throws Exception { + // Test completion of element names + checkApplyLayoutCompletion("completion1.xml", "<T^extView", "TableLayout"); + } + + public void testApplyCompletion11a() throws Exception { + // Test completion of element names at the outside of the <. This should include + // all the elements too (along with the leading <). + checkApplyLayoutCompletion("completion1.xml", "^<TextView", "<RadioGroup ></RadioGroup>"); + } + + public void testApplyCompletion11b() throws Exception { + // Similar to testApplyCompletion11a, but replacing with an element that does not + // have children (to test the closing tag insertion code) + checkApplyLayoutCompletion("completion1.xml", "^<TextView", "<CheckBox />"); + } + + public void testApplyCompletion12() throws Exception { + // Test completion of element names inside a nested XML; ensure that this will + // correctly compute element names, not previous attribute + checkApplyLayoutCompletion("completion1.xml", "btn_default\">^</FrameLayout>", + "<FrameLayout ></FrameLayout>"); + } + + public void testApplyCompletion13a() throws Exception { + checkApplyLayoutCompletion("completion2.xml", "gravity=\"left|bottom|^cen", + "fill_vertical"); + } + + public void testApplyCompletion13b() throws Exception { + checkApplyLayoutCompletion("completion2.xml", "gravity=\"left|bottom|cen^", + "center_horizontal"); + } + + public void testApplyCompletion13c() throws Exception { + checkApplyLayoutCompletion("completion2.xml", "gravity=\"left|bottom^|cen", + "bottom|fill_horizontal"); + } + + // --- Code Completion test infrastructure ---- + + private void checkLayoutCompletion(String name, String caretLocation) throws Exception { + checkCompletion(name, getLayoutFile(getProject(), name), caretLocation, + new LayoutContentAssist()); + } + + private void checkManifestCompletion(String name, String caretLocation) throws Exception { + // Manifest files must be named AndroidManifest.xml. Must overwrite to replace + // the default manifest created in the test project. + IFile file = getTestDataFile(getProject(), name, "AndroidManifest.xml", true); + + checkCompletion(name, file, caretLocation, + new ManifestContentAssist()); + } + + private void checkApplyLayoutCompletion(String name, String caretLocation, + String match) throws Exception { + checkApplyCompletion(name, getLayoutFile(getProject(), name), caretLocation, + new LayoutContentAssist(), match); + } + + private ICompletionProposal[] complete(IFile file, String caretLocation, + AndroidContentAssist assist) throws Exception { + + // Determine the offset + String fileContent = AdtPlugin.readFile(file); + int caretDelta = caretLocation.indexOf(CARET); + assertTrue(caretLocation, caretDelta != -1); + String caretContext = caretLocation.substring(0, caretDelta) + + caretLocation.substring(caretDelta + CARET.length()); + int caretContextIndex = fileContent.indexOf(caretContext); + assertTrue("Caret content " + caretContext + " not found in file", + caretContextIndex != -1); + int offset = caretContextIndex + caretDelta; + + // Open file + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + assertNotNull(page); + IEditorPart editor = IDE.openEditor(page, file); + assertTrue(editor instanceof AndroidXmlEditor); + AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor; + ISourceViewer viewer = layoutEditor.getStructuredSourceViewer(); + + // Run code completion + ICompletionProposal[] proposals = assist.computeCompletionProposals(viewer, offset); + if (proposals == null) { + proposals = new ICompletionProposal[0]; + } + + return proposals; + } + + private void checkApplyCompletion(String basename, IFile file, String caretLocation, + AndroidContentAssist assist, String match) throws Exception { + ICompletionProposal[] proposals = complete(file, caretLocation, assist); + ICompletionProposal chosen = null; + for (ICompletionProposal proposal : proposals) { + if (proposal.getDisplayString().equals(match)) { + chosen = proposal; + break; + } + } + assertNotNull(chosen); + assert chosen != null; // Eclipse null pointer analysis doesn't believe the JUnit assertion + + String fileContent = AdtPlugin.readFile(file); + IDocument document = new Document(); + document.set(fileContent); + + // Apply code completion + chosen.apply(document); + + // Insert caret location as well + Point location = chosen.getSelection(document); + document.replace(location.x, 0, CARET); + + String actual = document.get(); + + String diff = getDiff(fileContent, actual); + assertTrue(diff.length() > 0 || fileContent.equals(actual)); + + StringBuilder summary = new StringBuilder(); + summary.append("Code completion in " + basename + " for " + caretLocation + " selecting " + match + ":\n"); + summary.append(diff); + + //assertEqualsGolden(basename, actual); + assertEqualsGolden(basename, summary.toString(), "diff"); + } + + private void checkCompletion(String basename, IFile file, String caretLocation, + AndroidContentAssist assist) throws Exception { + ICompletionProposal[] proposals = complete(file, caretLocation, assist); + StringBuilder sb = new StringBuilder(1000); + sb.append("Code completion in " + basename + " for " + caretLocation + ":\n"); + for (ICompletionProposal proposal : proposals) { + sb.append(proposal.getDisplayString()); + String help = proposal.getAdditionalProposalInfo(); + if (help != null && help.trim().length() > 0) { + sb.append(" : "); + sb.append(help.replace('\n', ' ')); + } + sb.append('\n'); + } + assertEqualsGolden(basename, sb.toString(), "txt"); + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java index b18afa1..4281077 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/AdtProjectTest.java @@ -15,6 +15,9 @@ */ package com.android.ide.eclipse.adt.internal.editors.layout.refactoring; +import static com.android.AndroidConstants.FD_RES_LAYOUT; +import static com.android.sdklib.SdkConstants.FD_RES; + import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor; import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor; @@ -27,13 +30,16 @@ import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard; import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectCreationPage; import com.android.ide.eclipse.tests.SdkTestCase; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.wizard.IWizardContainer; import org.eclipse.jface.wizard.IWizardPage; @@ -82,28 +88,53 @@ public class AdtProjectTest extends SdkTestCase { return getTestDataFile(project, name, name); } + protected IFile getLayoutFile(IProject project, String name) throws Exception { + return getTestDataFile(project, name, FD_RES + "/" + FD_RES_LAYOUT + "/" + name); + } + protected IFile getTestDataFile(IProject project, String sourceName, String destPath) throws Exception { + return getTestDataFile(project, sourceName, destPath, false); + } + + protected IFile getTestDataFile(IProject project, String sourceName, + String destPath, boolean overwrite) throws Exception { String[] split = destPath.split("/"); //$NON-NLS-1$ - assertTrue(split.length > 1); - IFolder folder = project.getFolder(split[0]); - NullProgressMonitor monitor = new NullProgressMonitor(); - if (!folder.exists()) { - folder.create(true /* force */, true /* local */, monitor); + IContainer parent; + String name; + if (split.length == 1) { + parent = project; + name = destPath; + } else { + IFolder folder = project.getFolder(split[0]); + NullProgressMonitor monitor = new NullProgressMonitor(); + if (!folder.exists()) { + folder.create(true /* force */, true /* local */, monitor); + } + for (int i = 1, n = split.length; i < n -1; i++) { + IFolder subFolder = folder.getFolder(split[i]); + if (!subFolder.exists()) { + subFolder.create(true /* force */, true /* local */, monitor); + } + folder = subFolder; + } + name = split[split.length - 1]; + parent = folder; } - for (int i = 1, n = split.length; i < n -1; i++) { - IFolder subFolder = folder.getFolder(split[i]); - if (!subFolder.exists()) { - subFolder.create(true /* force */, true /* local */, monitor); + IFile file = parent.getFile(new Path(name)); + if (overwrite && file.exists()) { + String currentContents = AdtPlugin.readFile(file); + String newContents = readTestFile(sourceName, true); + if (currentContents == null || !currentContents.equals(newContents)) { + file.delete(true, new NullProgressMonitor()); + } else { + return file; } - folder = subFolder; } - - String name = split[split.length - 1]; - IFile file = folder.getFile(name); if (!file.exists()) { String xml = readTestFile(sourceName, true); InputStream bstream = new ByteArrayInputStream(xml.getBytes("UTF-8")); //$NON-NLS-1$ + NullProgressMonitor monitor = new NullProgressMonitor(); file.create(bstream, false /* force */, monitor); } @@ -161,6 +192,52 @@ public class AdtProjectTest extends SdkTestCase { return iproject; } + /** + * Very primitive line differ, intended for files where there are very minor changes + * (such as code completion apply-tests) + */ + protected String getDiff(String before, String after) { + + // Do line by line analysis + String[] beforeLines = before.split("\n"); + String[] afterLines = after.split("\n"); + + int firstDelta = 0; + for (; firstDelta < Math.min(beforeLines.length, afterLines.length); firstDelta++) { + if (!beforeLines[firstDelta].equals(afterLines[firstDelta])) { + break; + } + } + + if (firstDelta == beforeLines.length && firstDelta == afterLines.length) { + return ""; + } + + // Counts from the end of both arrays + int lastDelta = 0; + for (; lastDelta < Math.min(beforeLines.length, afterLines.length); lastDelta++) { + if (!beforeLines[beforeLines.length - 1 - lastDelta].equals( + afterLines[afterLines.length - 1 - lastDelta])) { + break; + } + } + + StringBuilder sb = new StringBuilder(); + for (int i = firstDelta; i < beforeLines.length - lastDelta; i++) { + sb.append("< "); + sb.append(beforeLines[i]); + sb.append('\n'); + } + sb.append("---\n"); + for (int i = firstDelta; i < afterLines.length - lastDelta; i++) { + sb.append("> "); + sb.append(afterLines[i]); + sb.append('\n'); + } + + return sb.toString(); + } + public static ViewElementDescriptor createDesc(String name, String fqn, boolean hasChildren) { if (hasChildren) { return new ViewElementDescriptor(name, name, fqn, "", "", new AttributeDescriptor[0], @@ -203,6 +280,55 @@ public class AdtProjectTest extends SdkTestCase { return xml; } + protected void assertEqualsGolden(String basename, String actual) { + assertEqualsGolden(basename, actual, basename.substring(basename.lastIndexOf('.') + 1)); + } + + protected void assertEqualsGolden(String basename, String actual, String newExtension) { + String testName = getName(); + if (testName.startsWith("test")) { + testName = testName.substring(4); + if (Character.isUpperCase(testName.charAt(0))) { + testName = Character.toLowerCase(testName.charAt(0)) + testName.substring(1); + } + } + String expectedName; + String extension = basename.substring(basename.lastIndexOf('.') + 1); + if (newExtension == null) { + newExtension = extension; + } + expectedName = basename.substring(0, basename.indexOf('.')) + + "-expected-" + testName + '.' + newExtension; + String expected = readTestFile(expectedName, false); + if (expected == null) { + File expectedPath = new File(getTempDir(), expectedName); + AdtPlugin.writeFile(expectedPath, actual); + System.out.println("Expected - written to " + expectedPath + ":\n"); + System.out.println(actual); + fail("Did not find golden file (" + expectedName + "): Wrote contents as " + + expectedPath); + } else { + if (!expected.equals(actual)) { + File expectedPath = new File(getTempDir(), expectedName); + File actualPath = new File(getTempDir(), + expectedName.replace("expected", "actual")); + AdtPlugin.writeFile(expectedPath, expected); + AdtPlugin.writeFile(actualPath, actual); + System.out.println("The files differ - see " + expectedPath + " versus " + + actualPath); + assertEquals("The files differ - see " + expectedPath + " versus " + actualPath, + expected, actual); + } + } + } + + protected File getTempDir() { + if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN) { + return new File("/tmp"); //$NON-NLS-1$ + } + return new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$ + } + /** Special editor context set on the model to be rendered */ protected static class TestLayoutEditor extends LayoutEditor { private final IFile mFile; diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RefactoringTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RefactoringTest.java index 372026c..947840c 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RefactoringTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/RefactoringTest.java @@ -15,21 +15,15 @@ */ package com.android.ide.eclipse.adt.internal.editors.layout.refactoring; -import static com.android.AndroidConstants.FD_RES_LAYOUT; import static com.android.ide.common.layout.LayoutConstants.ANDROID_WIDGET_PREFIX; -import static com.android.ide.eclipse.adt.AdtConstants.DOT_XML; -import static com.android.sdklib.SdkConstants.FD_RES; import com.android.ide.common.rendering.api.ViewInfo; -import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo; import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities; import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode; import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode; -import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; @@ -46,7 +40,6 @@ import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.w3c.dom.Element; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -59,10 +52,6 @@ import java.util.regex.Pattern; @SuppressWarnings("restriction") public class RefactoringTest extends AdtProjectTest { - protected IFile getLayoutFile(IProject project, String name) throws Exception { - return getTestDataFile(project, name, FD_RES + "/" + FD_RES_LAYOUT + "/" + name); - } - protected static Element findElementById(Element root, String id) { if (id.equals(VisualRefactoring.getId(root))) { return root; @@ -153,44 +142,6 @@ public class RefactoringTest extends AdtProjectTest { } } - protected void assertEqualsGolden(String basename, String actual) { - String testName = getName(); - if (testName.startsWith("test")) { - testName = testName.substring(4); - if (Character.isUpperCase(testName.charAt(0))) { - testName = Character.toLowerCase(testName.charAt(0)) + testName.substring(1); - } - } - String expectedName; - if (basename.endsWith(DOT_XML)) { - expectedName = basename.substring(0, basename.length() - DOT_XML.length()) - + "-expected-" + testName + DOT_XML; - } else { - expectedName = basename + ".expected"; - } - String expected = readTestFile(expectedName, false); - if (expected == null) { - File expectedPath = new File(getTempDir(), expectedName); - AdtPlugin.writeFile(expectedPath, actual); - System.out.println("Expected - written to " + expectedPath + ":\n"); - System.out.println(actual); - fail("Did not find golden file (" + expectedName + "): Wrote contents as " - + expectedPath); - } else { - if (!expected.equals(actual)) { - File expectedPath = new File(getTempDir(), expectedName); - File actualPath = new File(getTempDir(), - expectedName.replace("expected", "actual")); - AdtPlugin.writeFile(expectedPath, expected); - AdtPlugin.writeFile(actualPath, actual); - System.out.println("The files differ - see " + expectedPath + " versus " - + actualPath); - assertEquals("The files differ - see " + expectedPath + " versus " + actualPath, - expected, actual); - } - } - } - protected UiViewElementNode createModel(UiViewElementNode parent, Element element) { List<Element> children = DomUtilities.getChildren(element); String fqcn = ANDROID_WIDGET_PREFIX + element.getTagName(); @@ -260,13 +211,6 @@ public class RefactoringTest extends AdtProjectTest { return view; } - protected File getTempDir() { - if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN) { - return new File("/tmp"); //$NON-NLS-1$ - } - return new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$ - } - protected TestContext setupTestContext(IFile file, String relativePath) throws Exception { IStructuredModel structuredModel = null; org.w3c.dom.Document domDocument = null; diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-actual-applyCompletion1.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-actual-applyCompletion1.xml new file mode 100644 index 0000000..2413658 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-actual-applyCompletion1.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"> +<!-- + This file deliberately contains errors - it represents partial keyboard + typing for interactive code completion +--> + <TextView + android:layout_weight^="fill_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@android:dimen/app_icon_size" + android:layout_marginLeft="50dp" + android:layout_marginBottom="50" + android:textColor="#000000" + style="@android:style/Widget.Button" + android:gravity="left|bottom" + android:text="@string/hello" + android:hint="hint" /> + <FrameLayout android:foreground="@android:drawable/btn_default"></FrameLayout> +</LinearLayout> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion1.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion1.diff new file mode 100644 index 0000000..08ba349 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion1.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_w^idth="fill_parent" selecting android:layout_weight: +< android:layout_width="fill_parent" +--- +> android:layout_weight^="fill_parent" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion10.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion10.diff new file mode 100644 index 0000000..4cde056 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion10.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for <T^extView selecting TableLayout: +< <TextView +--- +> <TableLayout^ diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion11a.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion11a.diff new file mode 100644 index 0000000..7d1fd13 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion11a.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for ^<TextView selecting <RadioGroup ></RadioGroup>: +< <TextView +--- +> <RadioGroup ^></RadioGroup><TextView diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion11b.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion11b.diff new file mode 100644 index 0000000..62bf772 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion11b.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for ^<TextView selecting <CheckBox />: +< <TextView +--- +> <CheckBox ^/><TextView diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion12.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion12.diff new file mode 100644 index 0000000..2d767a9 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion12.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for btn_default">^</FrameLayout> selecting <FrameLayout ></FrameLayout>: +< <FrameLayout android:foreground="@android:drawable/btn_default"></FrameLayout> +--- +> <FrameLayout android:foreground="@android:drawable/btn_default"><FrameLayout ^></FrameLayout></FrameLayout> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion2.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion2.diff new file mode 100644 index 0000000..8e0b3e4 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion2.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_width="^fill_parent" selecting match_parent: +< android:layout_width="fill_parent" +--- +> android:layout_width="match_parent^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion3.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion3.diff new file mode 100644 index 0000000..5b956a5 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion3.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_width="fi^ll_parent" selecting fill_parent: +< android:layout_width="fill_parent" +--- +> android:layout_width="fill_parent^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion4.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion4.diff new file mode 100644 index 0000000..818b1fa --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion4.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for marginBottom="50^" selecting 50mm: +< android:layout_marginBottom="50" +--- +> android:layout_marginBottom="50mm^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion5.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion5.diff new file mode 100644 index 0000000..5571fd7 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion5.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_marginLeft="50d^p" selecting 50dp: +< android:layout_marginLeft="50dp" +--- +> android:layout_marginLeft="50dp^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion6.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion6.diff new file mode 100644 index 0000000..404b2a9 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion6.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for style="@android:^style/Widget.Button" selecting @android:drawable/: +< style="@android:style/Widget.Button" +--- +> style="@android:drawable/^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion7a.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion7a.diff new file mode 100644 index 0000000..e1d019a --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion7a.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for android:gravity="l^eft|bottom" selecting left: +< android:gravity="left|bottom" +--- +> android:gravity="left^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion7b.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion7b.diff new file mode 100644 index 0000000..2fbd2e5 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion7b.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for android:gravity="left|b^ottom" selecting bottom: +< android:gravity="left|bottom" +--- +> android:gravity="left|bottom^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion8.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion8.diff new file mode 100644 index 0000000..dafdeff --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion8.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_width^="fill_parent" selecting android:layout_width: +< android:layout_width="fill_parent" +--- +> android:layout_width^="fill_parent" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion9.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion9.diff new file mode 100644 index 0000000..be0c226 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-applyCompletion9.diff @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_width=^"fill_parent" selecting "wrap_content": +< android:layout_width="fill_parent" +--- +> android:layout_width="wrap_content^" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion1.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion1.txt new file mode 100644 index 0000000..949067a --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion1.txt @@ -0,0 +1,3 @@ +Code completion in completion1.xml for layout_w^idth="fill_parent": +android:layout_width : Specifies the basic width of the view. [dimension, enum] +android:layout_weight : [float] diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion10.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion10.txt new file mode 100644 index 0000000..68efdfb --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion10.txt @@ -0,0 +1,10 @@ +Code completion in completion1.xml for <T^extView: +TabHost +TabWidget +TableLayout +TableRow +TextSwitcher +TextView +TimePicker +ToggleButton +TwoLineListItem diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion11.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion11.txt new file mode 100644 index 0000000..670b03e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion11.txt @@ -0,0 +1,60 @@ +Code completion in completion1.xml for ^<TextView: +<AbsoluteLayout ></AbsoluteLayout> +<AdapterViewFlipper ></AdapterViewFlipper> +<DialerFilter ></DialerFilter> +<ExpandableListView ></ExpandableListView> +<FrameLayout ></FrameLayout> +<GridView ></GridView> +<HorizontalScrollView ></HorizontalScrollView> +<ImageSwitcher ></ImageSwitcher> +<LinearLayout ></LinearLayout> +<ListView ></ListView> +<MediaController ></MediaController> +<RadioGroup ></RadioGroup> +<RelativeLayout ></RelativeLayout> +<ScrollView ></ScrollView> +<SearchView ></SearchView> +<SlidingDrawer ></SlidingDrawer> : SlidingDrawer specific attributes. +<StackView ></StackView> +<TabHost ></TabHost> +<TabWidget ></TabWidget> +<TableLayout ></TableLayout> +<TableRow ></TableRow> +<TextSwitcher ></TextSwitcher> +<ViewAnimator ></ViewAnimator> +<ViewFlipper ></ViewFlipper> +<ViewSwitcher ></ViewSwitcher> +<GestureOverlayView /> : GestureOverlayView specific attributes. +<SurfaceView /> +<View /> : Attributes that can be used with android.view.View or any of its subclasses. +<ViewStub /> : A android.view.ViewStub lets you lazily include other XML layouts inside your application at runtime. +<WebView /> +<AnalogClock /> +<AutoCompleteTextView /> +<Button /> +<CalendarView /> +<CheckBox /> +<CheckedTextView /> +<Chronometer /> +<DatePicker /> +<DigitalClock /> +<EditText /> +<Gallery /> +<ImageButton /> +<ImageView /> +<MultiAutoCompleteTextView /> +<NumberPicker /> +<ProgressBar /> +<QuickContactBadge /> +<RadioButton /> +<RatingBar /> +<SeekBar /> +<Spinner /> +<TextView /> +<TimePicker /> +<ToggleButton /> +<TwoLineListItem /> +<VideoView /> +<ZoomButton /> +<ZoomControls /> +<include /> : Lets you statically include XML layouts inside other XML layouts. diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion12.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion12.txt new file mode 100644 index 0000000..4af986b --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion12.txt @@ -0,0 +1,60 @@ +Code completion in completion1.xml for btn_default">^</FrameLayout>: +<AbsoluteLayout ></AbsoluteLayout> +<AdapterViewFlipper ></AdapterViewFlipper> +<DialerFilter ></DialerFilter> +<ExpandableListView ></ExpandableListView> +<FrameLayout ></FrameLayout> +<GridView ></GridView> +<HorizontalScrollView ></HorizontalScrollView> +<ImageSwitcher ></ImageSwitcher> +<LinearLayout ></LinearLayout> +<ListView ></ListView> +<MediaController ></MediaController> +<RadioGroup ></RadioGroup> +<RelativeLayout ></RelativeLayout> +<ScrollView ></ScrollView> +<SearchView ></SearchView> +<SlidingDrawer ></SlidingDrawer> : SlidingDrawer specific attributes. +<StackView ></StackView> +<TabHost ></TabHost> +<TabWidget ></TabWidget> +<TableLayout ></TableLayout> +<TableRow ></TableRow> +<TextSwitcher ></TextSwitcher> +<ViewAnimator ></ViewAnimator> +<ViewFlipper ></ViewFlipper> +<ViewSwitcher ></ViewSwitcher> +<GestureOverlayView /> : GestureOverlayView specific attributes. +<SurfaceView /> +<View /> : Attributes that can be used with android.view.View or any of its subclasses. +<ViewStub /> : A android.view.ViewStub lets you lazily include other XML layouts inside your application at runtime. +<WebView /> +<AnalogClock /> +<AutoCompleteTextView /> +<Button /> +<CalendarView /> +<CheckBox /> +<CheckedTextView /> +<Chronometer /> +<DatePicker /> +<DigitalClock /> +<EditText /> +<Gallery /> +<ImageButton /> +<ImageView /> +<MultiAutoCompleteTextView /> +<NumberPicker /> +<ProgressBar /> +<QuickContactBadge /> +<RadioButton /> +<RatingBar /> +<SeekBar /> +<Spinner /> +<TextView /> +<TimePicker /> +<ToggleButton /> +<TwoLineListItem /> +<VideoView /> +<ZoomButton /> +<ZoomControls /> +<include /> : Lets you statically include XML layouts inside other XML layouts. diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion2.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion2.txt new file mode 100644 index 0000000..136a6fe --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion2.txt @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_width="^fill_parent": +fill_parent +match_parent +wrap_content diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion3.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion3.txt new file mode 100644 index 0000000..09c27ce --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion3.txt @@ -0,0 +1,2 @@ +Code completion in completion1.xml for layout_width="fi^ll_parent": +fill_parent diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion4.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion4.txt new file mode 100644 index 0000000..a9111eb --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion4.txt @@ -0,0 +1,7 @@ +Code completion in completion1.xml for marginBottom="50^": +50dp : <b>Density-independent Pixels</b> - an abstract unit that is based on the physical density of the screen. +50sp : <b>Scale-independent Pixels</b> - this is like the dp unit, but it is also scaled by the user's font size preference. +50pt : <b>Points</b> - 1/72 of an inch based on the physical size of the screen. +50mm : <b>Millimeters</b> - based on the physical size of the screen. +50in : <b>Inches</b> - based on the physical size of the screen. +50px : <b>Pixels</b> - corresponds to actual pixels on the screen. Not recommended. diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion5.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion5.txt new file mode 100644 index 0000000..6b1c993 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion5.txt @@ -0,0 +1,2 @@ +Code completion in completion1.xml for layout_marginLeft="50d^p": +50dp : <b>Density-independent Pixels</b> - an abstract unit that is based on the physical density of the screen. diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion6.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion6.txt new file mode 100644 index 0000000..0853a83 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion6.txt @@ -0,0 +1,22 @@ +Code completion in completion1.xml for style="@android:^style/Widget.Button": +@android:style/ +@android:anim/ +@android:animator/ +@android:array/ +@android:bool/ +@android:color/ +@android:declare-styleable/ +@android:dimen/ +@android:drawable/ +@android:fraction/ +@android:id/ +@android:integer/ +@android:interpolator/ +@android:layout/ +@android:menu/ +@android:mipmap/ +@android:plurals/ +@android:public/ +@android:raw/ +@android:string/ +@android:xml/ diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion7a.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion7a.txt new file mode 100644 index 0000000..cf373ad --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion7a.txt @@ -0,0 +1,2 @@ +Code completion in completion1.xml for android:gravity="l^eft|bottom": +left diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion7b.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion7b.txt new file mode 100644 index 0000000..66276d6 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion7b.txt @@ -0,0 +1,2 @@ +Code completion in completion1.xml for android:gravity="left|b^ottom": +bottom diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion8.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion8.txt new file mode 100644 index 0000000..bee7f93 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion8.txt @@ -0,0 +1,2 @@ +Code completion in completion1.xml for layout_width^="fill_parent": +android:layout_width : Specifies the basic width of the view. [dimension, enum] diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion9.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion9.txt new file mode 100644 index 0000000..ab6a0d2 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1-expected-completion9.txt @@ -0,0 +1,4 @@ +Code completion in completion1.xml for layout_width=^"fill_parent": +"fill_parent" +"match_parent" +"wrap_content" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1.xml new file mode 100644 index 0000000..d523eeb --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion1.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"> +<!-- + This file deliberately contains errors - it represents partial keyboard + typing for interactive code completion +--> + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@android:dimen/app_icon_size" + android:layout_marginLeft="50dp" + android:layout_marginBottom="50" + android:textColor="#000000" + style="@android:style/Widget.Button" + android:gravity="left|bottom" + android:text="@string/hello" + android:hint="hint" /> + <FrameLayout android:foreground="@android:drawable/btn_default"></FrameLayout> +</LinearLayout> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13a.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13a.diff new file mode 100644 index 0000000..e19874b --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13a.diff @@ -0,0 +1,4 @@ +Code completion in completion2.xml for gravity="left|bottom|^cen selecting fill_vertical: +< <TextView android:gravity="left|bottom|cen"></TextView> +--- +> <TextView android:gravity="left|bottom|fill_vertical^"></TextView> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13b.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13b.diff new file mode 100644 index 0000000..ddea7f1 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13b.diff @@ -0,0 +1,4 @@ +Code completion in completion2.xml for gravity="left|bottom|cen^ selecting center_horizontal: +< <TextView android:gravity="left|bottom|cen"></TextView> +--- +> <TextView android:gravity="left|bottom|center_horizontal^"></TextView> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13c.diff b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13c.diff new file mode 100644 index 0000000..dec1691 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-applyCompletion13c.diff @@ -0,0 +1,4 @@ +Code completion in completion2.xml for gravity="left|bottom^|cen selecting bottom|fill_horizontal: +< <TextView android:gravity="left|bottom|cen"></TextView> +--- +> <TextView android:gravity="left|bottom|fill_horizontal^"></TextView> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13a.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13a.txt new file mode 100644 index 0000000..323bb78 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13a.txt @@ -0,0 +1,13 @@ +Code completion in completion2.xml for gravity="left|bottom|^cen: +top +bottom +left +right +center_vertical +fill_vertical +center_horizontal +fill_horizontal +center +fill +clip_vertical +clip_horizontal diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13b.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13b.txt new file mode 100644 index 0000000..8e6d4d8 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13b.txt @@ -0,0 +1,4 @@ +Code completion in completion2.xml for gravity="left|bottom|cen^: +center_vertical +center_horizontal +center diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13c.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13c.txt new file mode 100644 index 0000000..3e292ce --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2-expected-completion13c.txt @@ -0,0 +1,12 @@ +Code completion in completion2.xml for gravity="left|bottom^|cen: +bottom +bottom|top +bottom|right +bottom|center_vertical +bottom|fill_vertical +bottom|center_horizontal +bottom|fill_horizontal +bottom|center +bottom|fill +bottom|clip_vertical +bottom|clip_horizontal diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2.xml new file mode 100644 index 0000000..0921674 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/completion2.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Test multiple pipes in the flag value --> + <TextView android:gravity="left|bottom|cen"></TextView> +</LinearLayout> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion14.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion14.txt new file mode 100644 index 0000000..478e435 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion14.txt @@ -0,0 +1,10 @@ +Code completion in manifest.xml for android.permission.ACC^ESS_NETWORK_STATE: +android.permission.ACCESS_CHECKIN_PROPERTIES +android.permission.ACCESS_COARSE_LOCATION +android.permission.ACCESS_FINE_LOCATION +android.permission.ACCESS_LOCATION_EXTRA_COMMANDS +android.permission.ACCESS_MOCK_LOCATION +android.permission.ACCESS_NETWORK_STATE +android.permission.ACCESS_SURFACE_FLINGER +android.permission.ACCESS_WIFI_STATE +android.permission.ACCOUNT_MANAGER diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion15.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion15.txt new file mode 100644 index 0000000..c6b3538 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion15.txt @@ -0,0 +1,3 @@ +Code completion in manifest.xml for android.intent.category.L^AUNCHER: +android.intent.category.LAUNCHER +android.intent.category.LE_DESK_DOCK diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion16.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion16.txt new file mode 100644 index 0000000..b69522c --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion16.txt @@ -0,0 +1,14 @@ +Code completion in manifest.xml for <^application android:i: +application : The "application" tag describes application-level components contained in the package, as well as general application attributes. +instrumentation : Attributes that can be supplied in an AndroidManifest.xml "instrumentation" tag, a child of the root manifest tag. +uses-feature : The "uses-feature" tag specifies a specific feature used by the application. +permission-group : The "permission-group" tag declares a logical grouping of related permissions. +supports-screens : The "supports-screens" specifies the screen dimensions an application supports. +protected-broadcast : Private tag to declare system protected broadcast actions. +uses-configuration : The "uses-configuration" tag specifies a specific hardware configuration value used by the application. +compatible-screens +permission : The "permission" tag declares a security permission that can be used to control access from other packages to specific components or features in your package (or other packages). +uses-sdk : The "uses-sdk" tag describes the SDK features that the containing package must be running on to operate correctly. +permission-tree : The "permission-tree" tag declares the base of a tree of permission values: it declares that this package has ownership of the given permission name, as well as all names underneath it (separated by '.'). +uses-permission : The "uses-permission" tag requests a "permission" that the containing package must be granted in order for it to operate correctly. +original-package : Private tag to declare the original package name that this package is based on. diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion17.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion17.txt new file mode 100644 index 0000000..6d966da --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion17.txt @@ -0,0 +1,7 @@ +Code completion in manifest.xml for ^android:versionCode="1": +package : This attribute gives a unique name for the package, using a Java-style naming convention to avoid name collisions. For example, applications published by Google could have names of the form com.google.app.appname +android:versionCode : Internal version code. [integer] +android:versionName : The text shown to the user to indicate the version they have. [string] +android:sharedUserId : Specify the name of a user ID that will be shared between multiple packages. [string] +android:sharedUserLabel : Specify a label for the shared user UID of this package. [reference] +android:installLocation : The default install location defined by an application. [enum] diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion18.txt b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion18.txt new file mode 100644 index 0000000..6fd1096 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest-expected-completion18.txt @@ -0,0 +1,27 @@ +Code completion in manifest.xml for <activity android:^name=".TestActivity": +android:name : Required name of the class implementing the activity, deriving from android.app.Activity. [string] +android:theme : The overall theme to use for an activity. [reference] +android:label : A user-legible name for the given item. [string, reference] +android:description : Descriptive text for the associated data. [reference] +android:icon : A Drawable resource providing a graphical representation of its associated item. [reference] +android:logo : A Drawable resource providing an extended graphical logo for its associated item. [reference] +android:launchMode : Specify how an activity should be launched. [enum] +android:screenOrientation : Specify the orientation an activity should be run in. [enum] +android:configChanges : Specify one or more configuration changes that the activity will handle itself. [flag] +android:permission : Specify a permission that a client is required to have in order to use the associated object. [string] +android:multiprocess : Specify whether a component is allowed to have multiple instances of itself running in different processes. [boolean] +android:process : Specify a specific process that the associated code is to run in. [string] +android:taskAffinity : Specify a task name that activities have an "affinity" to. [string] +android:allowTaskReparenting : Specify that an activity can be moved out of a task it is in to the task it has an affinity for when appropriate. [boolean] +android:finishOnTaskLaunch : Specify whether an activity should be finished when its task is brought to the foreground by relaunching from the home screen. [boolean] +android:finishOnCloseSystemDialogs : Specify whether an activity should be finished when a "close system windows" request has been made. [boolean] +android:clearTaskOnLaunch : Specify whether an activity's task should be cleared when it is re-launched from the home screen. [boolean] +android:noHistory : Specify whether an activity should be kept in its history stack. [boolean] +android:alwaysRetainTaskState : Specify whether an acitivty's task state should always be maintained by the system, or if it is allowed to reset the task to its initial state in certain situations. [boolean] +android:stateNotNeeded : Indicates that an Activity does not need to have its freeze state (as returned by onSaveInstanceState retained in order to be restarted. [boolean] +android:excludeFromRecents : Indicates that an Activity should be excluded from the list of recently launched activities. [boolean] +android:enabled : Specify whether the activity is enabled or not (that is, can be instantiated by the system). [boolean] +android:exported : Flag indicating whether the given application component is available to other applications. [boolean] +android:windowSoftInputMode : Specify the default soft-input mode for the main window of this activity. [flag] +android:immersive : Flag declaring this activity to be 'immersive'; immersive activities should not be interrupted with other activities or notifications. [boolean] +android:hardwareAccelerated : <p>Flag indicating whether the application's rendering should be hardware accelerated if possible. [boolean] diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest.xml new file mode 100644 index 0000000..2c0024f --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/manifest.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="foo.bar" + android:versionCode="1" + android:versionName="1.0"> + <uses-sdk android:minSdkVersion="11" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + + <application android:icon="@drawable/icon" android:label="@string/app_name"> + <activity android:name=".TestActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + </application> +</manifest> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-changeLayout1a.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-changeLayout1a.xml index 98e0a8f..772f82a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-changeLayout1a.xml +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1a-expected-changeLayout1a.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/RelativeLayout1" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="FirstButton" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> - <Button android:layout_alignParentLeft="true" android:layout_alignBaseline="@+id/button2" android:layout_below="@+id/button1" android:layout_marginTop="2dip" android:text="SecondButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button2"></Button> + <Button android:layout_alignParentLeft="true" android:layout_alignBaseline="@+id/button2" android:layout_below="@+id/button1" android:layout_marginTop="2dp" android:text="SecondButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button2"></Button> <Button android:layout_toRightOf="@+id/button2" android:layout_alignBaseline="@+id/button2" android:layout_alignTop="@+id/button2" android:text="ThirdButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button3"></Button> <CheckBox android:layout_toRightOf="@+id/button3" android:layout_alignBaseline="@+id/button2" android:layout_below="@+id/button1" android:id="@+id/checkBox1" android:text="CheckBox" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox> <Button android:layout_alignParentLeft="true" android:layout_below="@+id/checkBox1" android:layout_height="wrap_content" android:text="FourthButton" android:id="@+id/button4" android:layout_width="match_parent"></Button> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1b-expected-changeLayout1b.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1b-expected-changeLayout1b.xml index 737e72d..f47e9be 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1b-expected-changeLayout1b.xml +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample1b-expected-changeLayout1b.xml @@ -10,7 +10,7 @@ android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> - <Button android:layout_alignParentLeft="true" android:layout_alignBaseline="@+id/button2" android:layout_below="@+id/button1" android:layout_marginTop="2dip" + <Button android:layout_alignParentLeft="true" android:layout_alignBaseline="@+id/button2" android:layout_below="@+id/button1" android:layout_marginTop="2dp" android:text="SecondButton" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample5-expected-changeLayout5.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample5-expected-changeLayout5.xml index fba3049..225476c 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample5-expected-changeLayout5.xml +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/sample5-expected-changeLayout5.xml @@ -3,7 +3,7 @@ <Button android:layout_centerHorizontal="true" android:layout_alignParentTop="true" android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"></Button> <Button android:layout_centerHorizontal="true" android:layout_below="@+id/button1" android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"></Button> <Button android:layout_alignParentRight="true" android:layout_below="@+id/button2" android:text="Button" android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right"></Button> - <Button android:layout_alignParentLeft="true" android:layout_alignBaseline="@+id/button4" android:layout_below="@+id/button3" android:layout_marginTop="70dip" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Button" android:id="@+id/button4" android:layout_width="wrap_content"></Button> + <Button android:layout_alignParentLeft="true" android:layout_alignBaseline="@+id/button4" android:layout_below="@+id/button3" android:layout_marginTop="70dp" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Button" android:id="@+id/button4" android:layout_width="wrap_content"></Button> <Button android:layout_toRightOf="@+id/button4" android:layout_alignBaseline="@+id/button4" android:layout_alignTop="@+id/button4" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="Button" android:id="@+id/button5" android:layout_width="wrap_content"></Button> <Button android:layout_toRightOf="@+id/button5" android:layout_alignParentBottom="true" android:layout_height="wrap_content" android:text="Button" android:id="@+id/button6" android:layout_width="wrap_content" android:layout_gravity="bottom"></Button> </RelativeLayout> diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/AbsoluteLayoutRuleTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/AbsoluteLayoutRuleTest.java index f4092eb..62725b8 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/AbsoluteLayoutRuleTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/layout/AbsoluteLayoutRuleTest.java @@ -60,8 +60,8 @@ public class AbsoluteLayoutRuleTest extends LayoutTestBase { // Drop preview "useStyle(DROP_PREVIEW), drawRect(Rect[30,-10,105,80])"); - assertEquals("30dip", inserted.getStringAttr(ANDROID_URI, "layout_x")); - assertEquals("-10dip", inserted.getStringAttr(ANDROID_URI, "layout_y")); + assertEquals("30dp", inserted.getStringAttr(ANDROID_URI, "layout_x")); + assertEquals("-10dp", inserted.getStringAttr(ANDROID_URI, "layout_y")); // Without drag bounds we should just draw guide lines instead inserted = dragInto(new Rect(0, 0, 0, 0), new Point(30, -10), 4, -1, @@ -70,8 +70,8 @@ public class AbsoluteLayoutRuleTest extends LayoutTestBase { "useStyle(GUIDELINE), drawLine(30,0,30,480), drawLine(0,-10,240,-10)", // Drop preview "useStyle(DROP_PREVIEW), drawLine(30,-10,240,-10), drawLine(30,-10,30,480)"); - assertEquals("30dip", inserted.getStringAttr(ANDROID_URI, "layout_x")); - assertEquals("-10dip", inserted.getStringAttr(ANDROID_URI, "layout_y")); + assertEquals("30dp", inserted.getStringAttr(ANDROID_URI, "layout_x")); + assertEquals("-10dp", inserted.getStringAttr(ANDROID_URI, "layout_y")); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java deleted file mode 100644 index 8151f3a..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssistTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.editors; - -import junit.framework.TestCase; - -public class AndroidContentAssistTest extends TestCase { - public void testStartsWith() { - assertTrue(AndroidContentAssist.startsWith("", "")); - assertTrue(AndroidContentAssist.startsWith("a", "")); - assertTrue(AndroidContentAssist.startsWith("A", "")); - assertTrue(AndroidContentAssist.startsWith("A", "a")); - assertTrue(AndroidContentAssist.startsWith("A", "A")); - assertTrue(AndroidContentAssist.startsWith("Ab", "a")); - assertTrue(AndroidContentAssist.startsWith("ab", "A")); - assertTrue(AndroidContentAssist.startsWith("ab", "AB")); - assertFalse(AndroidContentAssist.startsWith("ab", "ABc")); - assertFalse(AndroidContentAssist.startsWith("", "ABc")); - } -} |