| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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.tools.lint.detector.api; |
| |
| import static com.android.SdkConstants.AUTO_URI; |
| import static com.android.tools.lint.detector.api.TextFormat.HTML; |
| import static com.android.tools.lint.detector.api.TextFormat.RAW; |
| import static com.android.tools.lint.detector.api.TextFormat.TEXT; |
| |
| import junit.framework.TestCase; |
| |
| public class TextFormatTest extends TestCase { |
| private static String convertMarkup(String raw, TextFormat to) { |
| return RAW.convertTo(raw, to); |
| } |
| |
| public void testConvertMarkup() throws Exception { |
| assertEquals("", convertMarkup("", HTML)); |
| |
| // Normal escapes |
| assertEquals("foo bar", convertMarkup("foo bar", HTML)); |
| assertEquals("foo<br/>\nbar", convertMarkup("foo\nbar", HTML)); |
| assertEquals("foo<br/>\nbar", convertMarkup("foo\nbar", HTML)); |
| assertEquals("<&>'\"", convertMarkup("<&>'\"", HTML)); |
| |
| // HTML Formatting |
| assertEquals("<code>@TargetApi(11)</code>, ", convertMarkup("`@TargetApi(11)`, ", |
| HTML)); |
| assertEquals("with <code>getArguments()</code>.", |
| convertMarkup("with `getArguments()`.", HTML)); |
| assertEquals("(<code>dip</code>)", convertMarkup("(`dip`)", HTML)); |
| assertEquals(" <code>0dp</code> ", convertMarkup(" `0dp` ", HTML)); |
| assertEquals( |
| "resources under <code>$ANDROID_SK/platforms/android-$VERSION/data/res/.</code>", |
| convertMarkup( |
| "resources under `$ANDROID_SK/platforms/android-$VERSION/data/res/.`", |
| HTML)); |
| assertEquals("wrong format. Instead of <code>-keepclasseswithmembernames</code> use ", |
| convertMarkup("wrong format. Instead of `-keepclasseswithmembernames` use ", |
| HTML)); |
| assertEquals("<code>exported=false</code>)", convertMarkup("`exported=false`)", |
| HTML)); |
| assertEquals("by setting <code>inputType=\"text\"</code>.", |
| convertMarkup("by setting `inputType=\"text\"`.", HTML)); |
| assertEquals("* <code>View(Context context)</code><br/>\n", |
| convertMarkup("* `View(Context context)`\n", HTML)); |
| assertEquals("The <code>@+id/</code> syntax", convertMarkup("The `@+id/` syntax", |
| HTML)); |
| assertEquals("", convertMarkup("", HTML)); |
| assertEquals("", convertMarkup("", HTML)); |
| assertEquals("This is <b>bold</b>", convertMarkup("This is *bold*", HTML)); |
| assertEquals("Visit <a href=\"http://google.com\">http://google.com</a>.", |
| convertMarkup("Visit http://google.com.", HTML)); |
| assertEquals("This is <code>monospace</code>!", convertMarkup("This is `monospace`!", |
| HTML)); |
| assertEquals( |
| "See <a href=\"http://developer.android.com/reference/android/view/" + |
| "WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON\">http://developer." + |
| "android.com/reference/android/view/WindowManager.LayoutParams.html#" + |
| "FLAG_KEEP_SCREEN_ON</a>.", |
| convertMarkup( |
| "See http://developer.android.com/reference/android/view/WindowManager.Layout" + |
| "Params.html#FLAG_KEEP_SCREEN_ON.", HTML)); |
| |
| // Text formatting |
| assertEquals("@TargetApi(11), ", convertMarkup("`@TargetApi(11)`, ", TEXT)); |
| assertEquals("with getArguments().", convertMarkup("with `getArguments()`.", TEXT)); |
| assertEquals("bold", convertMarkup("*bold*", TEXT)); |
| assertEquals("Visit http://google.com.", convertMarkup("Visit http://google.com.", |
| TEXT)); |
| |
| // Corners (match at the beginning and end) |
| assertEquals("<b>bold</b>", convertMarkup("*bold*", HTML)); |
| assertEquals("<code>monospace</code>!", convertMarkup("`monospace`!", HTML)); |
| |
| // Not formatting |
| assertEquals("a*b", convertMarkup("a*b", HTML)); |
| assertEquals("a* b*", convertMarkup("a* b*", HTML)); |
| assertEquals("*a *b", convertMarkup("*a *b", HTML)); |
| assertEquals("Prefix is http:// ", convertMarkup("Prefix is http:// ", HTML)); |
| assertEquals("", convertMarkup("", HTML)); |
| assertEquals("", convertMarkup("", HTML)); |
| assertEquals("", convertMarkup("", HTML)); |
| assertEquals("", convertMarkup("", HTML)); |
| assertEquals("This is * not * bold", convertMarkup("This is * not * bold", HTML)); |
| assertEquals("* List item 1<br/>\n* List Item 2", |
| convertMarkup("* List item 1\n* List Item 2", HTML)); |
| assertEquals("myhttp://foo.bar", convertMarkup("myhttp://foo.bar", HTML)); |
| } |
| |
| public void testConvertMarkup2() throws Exception { |
| // http at the end: |
| // Explanation from ManifestDetector#TARGET_NEWER |
| String explanation = |
| "When your application runs on a version of Android that is more recent than your " + |
| "targetSdkVersion specifies that it has been tested with, various compatibility " + |
| "modes kick in. This ensures that your application continues to work, but it may " + |
| "look out of place. For example, if the targetSdkVersion is less than 14, your " + |
| "app may get an option button in the UI.\n" + |
| "\n" + |
| "To fix this issue, set the targetSdkVersion to the highest available value. Then " + |
| "test your app to make sure everything works correctly. You may want to consult " + |
| "the compatibility notes to see what changes apply to each version you are adding " + |
| "support for: " + |
| "http://developer.android.com/reference/android/os/Build.VERSION_CODES.html"; |
| |
| assertEquals( |
| "When your application runs on a version of Android that is more recent than your " + |
| "targetSdkVersion specifies that it has been tested with, various compatibility " + |
| "modes kick in. This ensures that your application continues to work, but it may " + |
| "look out of place. For example, if the targetSdkVersion is less than 14, your " + |
| "app may get an option button in the UI.<br/>\n" + |
| "<br/>\n" + |
| "To fix this issue, set the targetSdkVersion to the highest available value. Then " + |
| "test your app to make sure everything works correctly. You may want to consult " + |
| "the compatibility notes to see what changes apply to each version you are adding " + |
| "support for: " + |
| "<a href=\"http://developer.android.com/reference/android/os/Build.VERSION_CODES." + |
| "html\">http://developer.android.com/reference/android/os/Build.VERSION_CODES.html" + |
| "</a>", |
| convertMarkup(explanation, HTML)); |
| } |
| |
| public void testConvertMarkup3() throws Exception { |
| // embedded http markup test |
| // Explanation from NamespaceDetector#CUSTOMVIEW |
| String explanation = |
| "When using a custom view with custom attributes in a library project, the layout " + |
| "must use the special namespace " + AUTO_URI + " instead of a URI which includes " + |
| "the library project's own package. This will be used to automatically adjust the " + |
| "namespace of the attributes when the library resources are merged into the " + |
| "application project."; |
| assertEquals( |
| "When using a custom view with custom attributes in a library project, the layout " + |
| "must use the special namespace " + |
| "<a href=\"http://schemas.android.com/apk/res-auto\">" + |
| "http://schemas.android.com/apk/res-auto</a> " + |
| "instead of a URI which includes the library project's own package. " + |
| "This will be used to automatically adjust the namespace of the attributes when " + |
| "the library resources are merged into the application project.", |
| convertMarkup(explanation, HTML)); |
| } |
| |
| public void testConvertMarkup4() throws Exception { |
| // monospace test |
| String explanation = |
| "The manifest should contain a `<uses-sdk>` element which defines the " + |
| "minimum minimum API Level required for the application to run, " + |
| "as well as the target version (the highest API level you have tested " + |
| "the version for.)"; |
| |
| assertEquals( |
| "The manifest should contain a <code><uses-sdk></code> element which defines the " + |
| "minimum minimum API Level required for the application to run, " + |
| "as well as the target version (the highest API level you have tested " + |
| "the version for.)", |
| convertMarkup(explanation, HTML)); |
| } |
| |
| public void testConvertMarkup5() throws Exception { |
| // monospace and bold test |
| // From ManifestDetector#MULTIPLE_USES_SDK |
| String explanation = |
| "The `<uses-sdk>` element should appear just once; the tools will *not* merge the " + |
| "contents of all the elements so if you split up the attributes across multiple " + |
| "elements, only one of them will take effect. To fix this, just merge all the " + |
| "attributes from the various elements into a single <uses-sdk> element."; |
| |
| assertEquals( |
| "The <code><uses-sdk></code> element should appear just once; the tools " + |
| "will <b>not</b> merge the " + |
| "contents of all the elements so if you split up the attributes across multiple " + |
| "elements, only one of them will take effect. To fix this, just merge all the " + |
| "attributes from the various elements into a single <uses-sdk> element.", |
| convertMarkup(explanation, HTML)); |
| } |
| |
| public void testConvertMarkup6() throws Exception { |
| // Embedded code next to attributes |
| // From AlwaysShowActionDetector#ISSUE |
| String explanation = |
| "Using `showAsAction=\"always\"` in menu XML, or `MenuItem.SHOW_AS_ACTION_ALWAYS` in "+ |
| "Java code is usually a deviation from the user interface style guide." + |
| "Use `ifRoom` or the corresponding `MenuItem.SHOW_AS_ACTION_IF_ROOM` instead.\n" + |
| "\n" + |
| "If `always` is used sparingly there are usually no problems and behavior is " + |
| "roughly equivalent to `ifRoom` but with preference over other `ifRoom` " + |
| "items. Using it more than twice in the same menu is a bad idea.\n" + |
| "\n" + |
| "This check looks for menu XML files that contain more than two `always` " + |
| "actions, or some `always` actions and no `ifRoom` actions. In Java code, " + |
| "it looks for projects that contain references to `MenuItem.SHOW_AS_ACTION_ALWAYS` " + |
| "and no references to `MenuItem.SHOW_AS_ACTION_IF_ROOM`."; |
| |
| assertEquals( |
| "Using <code>showAsAction=\"always\"</code> in menu XML, or " + |
| "<code>MenuItem.SHOW_AS_ACTION_ALWAYS</code> in Java code is usually a deviation " + |
| "from the user interface style guide.Use <code>ifRoom</code> or the " + |
| "corresponding <code>MenuItem.SHOW_AS_ACTION_IF_ROOM</code> instead.<br/>\n" + |
| "<br/>\n" + |
| "If <code>always</code> is used sparingly there are usually no problems and " + |
| "behavior is roughly equivalent to <code>ifRoom</code> but with preference over " + |
| "other <code>ifRoom</code> items. Using it more than twice in the same menu " + |
| "is a bad idea.<br/>\n" + |
| "<br/>\n" + |
| "This check looks for menu XML files that contain more than two <code>always</code> " + |
| "actions, or some <code>always</code> actions and no <code>ifRoom</code> actions. " + |
| "In Java code, it looks for projects that contain references to " + |
| "<code>MenuItem.SHOW_AS_ACTION_ALWAYS</code> and no references to " + |
| "<code>MenuItem.SHOW_AS_ACTION_IF_ROOM</code>.", |
| convertMarkup(explanation, HTML)); |
| } |
| |
| public void testConvertSelf() throws Exception { |
| // No changes |
| assertEquals("`foo`<b>", RAW.convertTo("`foo`<b>", RAW)); |
| assertEquals("`foo`<b>", TEXT.convertTo("`foo`<b>", TEXT)); |
| assertEquals("`foo`<b>", HTML.convertTo("`foo`<b>", HTML)); |
| } |
| |
| public void testConvertFromHtml() throws Exception { |
| assertEquals("" |
| + "Line 1\n" |
| + "Line 2 <div>\n", |
| HTML.convertTo("<html>Line 1<br>Line 2\n<!-- comment --><div></html>", |
| TEXT)); |
| } |
| |
| public void testConvertFromHtml2() throws Exception { |
| assertEquals("" |
| + "Using showAsAction=\"always\" in menu XML, or\n" |
| + "MenuItem.SHOW_AS_ACTION_ALWAYS in Java code is usually a\n" |
| + "deviation from the user interface style guide.Use ifRoom or\n" |
| + "the corresponding MenuItem.SHOW_AS_ACTION_IF_ROOM instead.\n" |
| + "If always is used sparingly there are usually no problems\n" |
| + "and behavior is roughly equivalent to ifRoom but with\n" |
| + "preference over other ifRoom items. Using it more than twice\n" |
| + "in the same menu is a bad idea. This check looks for menu\n" |
| + "XML files that contain more than two always actions, or some\n" |
| + "always actions and no ifRoom actions. In Java code, it looks\n" |
| + "for projects that contain references to\n" |
| + "MenuItem.SHOW_AS_ACTION_ALWAYS and no references to\n" |
| + "MenuItem.SHOW_AS_ACTION_IF_ROOM.\n", |
| HTML.convertTo( |
| "Using <code>showAsAction=\"always\"</code> in menu XML, or " + |
| "<code>MenuItem.SHOW_AS_ACTION_ALWAYS</code> in Java code is usually a deviation " + |
| "from the user interface style guide.Use <code>ifRoom</code> or the " + |
| "corresponding <code>MenuItem.SHOW_AS_ACTION_IF_ROOM</code> instead.<br/>\n" + |
| "<br/>\n" + |
| "If <code>always</code> is used sparingly there are usually no problems and " + |
| "behavior is roughly equivalent to <code>ifRoom</code> but with preference over " + |
| "other <code>ifRoom</code> items. Using it more than twice in the same menu " + |
| "is a bad idea.<br/>\n" + |
| "<br/>\n" + |
| "This check looks for menu XML files that contain more than two <code>always</code> " + |
| "actions, or some <code>always</code> actions and no <code>ifRoom</code> actions. " + |
| "In Java code, it looks for projects that contain references to " + |
| "<code>MenuItem.SHOW_AS_ACTION_ALWAYS</code> and no references to " + |
| "<code>MenuItem.SHOW_AS_ACTION_IF_ROOM</code>.", |
| TEXT)); |
| } |
| |
| public void testNbsp() throws Exception { |
| assertEquals(" text", RAW.convertTo("\u00a0\u00A0text", HTML)); |
| } |
| } |