/*
* Copyright (C) 2011 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.tools.lint.detector.api.LintUtils.getLocaleAndRegion;
import static com.android.tools.lint.detector.api.LintUtils.isImported;
import static com.android.tools.lint.detector.api.LintUtils.splitPath;
import com.android.annotations.Nullable;
import com.android.tools.lint.LombokParser;
import com.android.tools.lint.Main;
import com.android.tools.lint.checks.BuiltinIssueRegistry;
import com.android.tools.lint.client.api.IJavaParser;
import com.android.tools.lint.client.api.LintDriver;
import com.google.common.collect.Iterables;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import junit.framework.TestCase;
import lombok.ast.Node;
@SuppressWarnings("javadoc")
public class LintUtilsTest extends TestCase {
public void testPrintList() throws Exception {
assertEquals("foo, bar, baz",
LintUtils.formatList(Arrays.asList("foo", "bar", "baz"), 3));
assertEquals("foo, bar, baz",
LintUtils.formatList(Arrays.asList("foo", "bar", "baz"), 5));
assertEquals("foo, bar, baz... (3 more)",
LintUtils.formatList(
Arrays.asList("foo", "bar", "baz", "4", "5", "6"), 3));
assertEquals("foo... (5 more)",
LintUtils.formatList(
Arrays.asList("foo", "bar", "baz", "4", "5", "6"), 1));
assertEquals("foo, bar, baz",
LintUtils.formatList(Arrays.asList("foo", "bar", "baz"), 0));
}
public void testEndsWith() throws Exception {
assertTrue(LintUtils.endsWith("Foo", ""));
assertTrue(LintUtils.endsWith("Foo", "o"));
assertTrue(LintUtils.endsWith("Foo", "oo"));
assertTrue(LintUtils.endsWith("Foo", "Foo"));
assertTrue(LintUtils.endsWith("Foo", "FOO"));
assertTrue(LintUtils.endsWith("Foo", "fOO"));
assertFalse(LintUtils.endsWith("Foo", "f"));
}
public void testStartsWith() throws Exception {
assertTrue(LintUtils.startsWith("FooBar", "Bar", 3));
assertTrue(LintUtils.startsWith("FooBar", "BAR", 3));
assertTrue(LintUtils.startsWith("FooBar", "Foo", 0));
assertFalse(LintUtils.startsWith("FooBar", "Foo", 2));
}
public void testIsXmlFile() throws Exception {
assertTrue(LintUtils.isXmlFile(new File("foo.xml")));
assertTrue(LintUtils.isXmlFile(new File("foo.Xml")));
assertTrue(LintUtils.isXmlFile(new File("foo.XML")));
assertFalse(LintUtils.isXmlFile(new File("foo.png")));
assertFalse(LintUtils.isXmlFile(new File("xml")));
assertFalse(LintUtils.isXmlFile(new File("xml.png")));
}
public void testGetBasename() throws Exception {
assertEquals("foo", LintUtils.getBaseName("foo.png"));
assertEquals("foo", LintUtils.getBaseName("foo.9.png"));
assertEquals(".foo", LintUtils.getBaseName(".foo"));
}
public void testEditDistance() {
assertEquals(0, LintUtils.editDistance("kitten", "kitten"));
// editing kitten to sitting has edit distance 3:
// replace k with s
// replace e with i
// append g
assertEquals(3, LintUtils.editDistance("kitten", "sitting"));
assertEquals(3, LintUtils.editDistance("saturday", "sunday"));
assertEquals(1, LintUtils.editDistance("button", "bitton"));
assertEquals(6, LintUtils.editDistance("radiobutton", "bitton"));
}
public void testSplitPath() throws Exception {
assertTrue(Arrays.equals(new String[] { "/foo", "/bar", "/baz" },
Iterables.toArray(splitPath("/foo:/bar:/baz"), String.class)));
assertTrue(Arrays.equals(new String[] { "/foo", "/bar" },
Iterables.toArray(splitPath("/foo;/bar"), String.class)));
assertTrue(Arrays.equals(new String[] { "/foo", "/bar:baz" },
Iterables.toArray(splitPath("/foo;/bar:baz"), String.class)));
assertTrue(Arrays.equals(new String[] { "\\foo\\bar", "\\bar\\foo" },
Iterables.toArray(splitPath("\\foo\\bar;\\bar\\foo"), String.class)));
assertTrue(Arrays.equals(new String[] { "${sdk.dir}\\foo\\bar", "\\bar\\foo" },
Iterables.toArray(splitPath("${sdk.dir}\\foo\\bar;\\bar\\foo"),
String.class)));
assertTrue(Arrays.equals(new String[] { "${sdk.dir}/foo/bar", "/bar/foo" },
Iterables.toArray(splitPath("${sdk.dir}/foo/bar:/bar/foo"),
String.class)));
assertTrue(Arrays.equals(new String[] { "C:\\foo", "/bar" },
Iterables.toArray(splitPath("C:\\foo:/bar"), String.class)));
}
public void testCommonParen1() {
assertEquals(new File("/a"), (LintUtils.getCommonParent(
new File("/a/b/c/d/e"), new File("/a/c"))));
assertEquals(new File("/a"), (LintUtils.getCommonParent(
new File("/a/c"), new File("/a/b/c/d/e"))));
assertEquals(new File("/"), LintUtils.getCommonParent(
new File("/foo/bar"), new File("/bar/baz")));
assertEquals(new File("/"), LintUtils.getCommonParent(
new File("/foo/bar"), new File("/")));
assertNull(LintUtils.getCommonParent(
new File("C:\\Program Files"), new File("F:\\")));
assertNull(LintUtils.getCommonParent(
new File("C:/Program Files"), new File("F:/")));
assertEquals(new File("/foo/bar/baz"), LintUtils.getCommonParent(
new File("/foo/bar/baz"), new File("/foo/bar/baz")));
assertEquals(new File("/foo/bar"), LintUtils.getCommonParent(
new File("/foo/bar/baz"), new File("/foo/bar")));
assertEquals(new File("/foo/bar"), LintUtils.getCommonParent(
new File("/foo/bar/baz"), new File("/foo/bar/foo")));
assertEquals(new File("/foo"), LintUtils.getCommonParent(
new File("/foo/bar"), new File("/foo/baz")));
assertEquals(new File("/foo"), LintUtils.getCommonParent(
new File("/foo/bar"), new File("/foo/baz")));
assertEquals(new File("/foo/bar"), LintUtils.getCommonParent(
new File("/foo/bar"), new File("/foo/bar/baz")));
}
public void testCommonParent2() {
assertEquals(new File("/"), LintUtils.getCommonParent(
Arrays.asList(new File("/foo/bar"), new File("/bar/baz"))));
assertEquals(new File("/"), LintUtils.getCommonParent(
Arrays.asList(new File("/foo/bar"), new File("/"))));
assertNull(LintUtils.getCommonParent(
Arrays.asList(new File("C:\\Program Files"), new File("F:\\"))));
assertNull(LintUtils.getCommonParent(
Arrays.asList(new File("C:/Program Files"), new File("F:/"))));
assertEquals(new File("/foo"), LintUtils.getCommonParent(
Arrays.asList(new File("/foo/bar"), new File("/foo/baz"))));
assertEquals(new File("/foo"), LintUtils.getCommonParent(
Arrays.asList(new File("/foo/bar"), new File("/foo/baz"),
new File("/foo/baz/f"))));
assertEquals(new File("/foo/bar"), LintUtils.getCommonParent(
Arrays.asList(new File("/foo/bar"), new File("/foo/bar/baz"),
new File("/foo/bar/foo2/foo3"))));
}
public void testStripIdPrefix() throws Exception {
assertEquals("foo", LintUtils.stripIdPrefix("@+id/foo"));
assertEquals("foo", LintUtils.stripIdPrefix("@id/foo"));
assertEquals("foo", LintUtils.stripIdPrefix("foo"));
}
public void testIdReferencesMatch() throws Exception {
assertTrue(LintUtils.idReferencesMatch("@+id/foo", "@+id/foo"));
assertTrue(LintUtils.idReferencesMatch("@id/foo", "@id/foo"));
assertTrue(LintUtils.idReferencesMatch("@id/foo", "@+id/foo"));
assertTrue(LintUtils.idReferencesMatch("@+id/foo", "@id/foo"));
assertFalse(LintUtils.idReferencesMatch("@+id/foo", "@+id/bar"));
assertFalse(LintUtils.idReferencesMatch("@id/foo", "@+id/bar"));
assertFalse(LintUtils.idReferencesMatch("@+id/foo", "@id/bar"));
assertFalse(LintUtils.idReferencesMatch("@+id/foo", "@+id/bar"));
assertFalse(LintUtils.idReferencesMatch("@+id/foo", "@+id/foo1"));
assertFalse(LintUtils.idReferencesMatch("@id/foo", "@id/foo1"));
assertFalse(LintUtils.idReferencesMatch("@id/foo", "@+id/foo1"));
assertFalse(LintUtils.idReferencesMatch("@+id/foo", "@id/foo1"));
assertFalse(LintUtils.idReferencesMatch("@+id/foo1", "@+id/foo"));
assertFalse(LintUtils.idReferencesMatch("@id/foo1", "@id/foo"));
assertFalse(LintUtils.idReferencesMatch("@id/foo1", "@+id/foo"));
assertFalse(LintUtils.idReferencesMatch("@+id/foo1", "@id/foo"));
}
private static void checkEncoding(String encoding, boolean writeBom, String lineEnding)
throws Exception {
StringBuilder sb = new StringBuilder();
// Norwegian extra vowel characters such as "latin small letter a with ring above"
String value = "\u00e6\u00d8\u00e5";
String expected = "First line." + lineEnding + "Second line." + lineEnding
+ "Third line." + lineEnding + value + lineEnding;
sb.append(expected);
File file = File.createTempFile("getEncodingTest" + encoding + writeBom, ".txt");
file.deleteOnExit();
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
OutputStreamWriter writer = new OutputStreamWriter(stream, encoding);
if (writeBom) {
String normalized = encoding.toLowerCase().replace("-", "_");
if (normalized.equals("utf_8")) {
stream.write(0xef);
stream.write(0xbb);
stream.write(0xbf);
} else if (normalized.equals("utf_16")) {
stream.write(0xfe);
stream.write(0xff);
} else if (normalized.equals("utf_16le")) {
stream.write(0xff);
stream.write(0xfe);
} else if (normalized.equals("utf_32")) {
stream.write(0x0);
stream.write(0x0);
stream.write(0xfe);
stream.write(0xff);
} else if (normalized.equals("utf_32le")) {
stream.write(0xff);
stream.write(0xfe);
stream.write(0x0);
stream.write(0x0);
} else {
fail("Can't write BOM for encoding " + encoding);
}
}
writer.write(sb.toString());
writer.close();
String s = LintUtils.getEncodedString(new Main(), file);
assertEquals(expected, s);
}
public void testGetEncodedString() throws Exception {
checkEncoding("utf-8", false /*bom*/, "\n");
checkEncoding("UTF-8", false /*bom*/, "\n");
checkEncoding("UTF_16", false /*bom*/, "\n");
checkEncoding("UTF-16", false /*bom*/, "\n");
checkEncoding("UTF_16LE", false /*bom*/, "\n");
// Try BOM's
checkEncoding("utf-8", true /*bom*/, "\n");
checkEncoding("UTF-8", true /*bom*/, "\n");
checkEncoding("UTF_16", true /*bom*/, "\n");
checkEncoding("UTF-16", true /*bom*/, "\n");
checkEncoding("UTF_16LE", true /*bom*/, "\n");
checkEncoding("UTF_32", true /*bom*/, "\n");
checkEncoding("UTF_32LE", true /*bom*/, "\n");
// Make sure this works for \r and \r\n as well
checkEncoding("UTF-16", false /*bom*/, "\r");
checkEncoding("UTF_16LE", false /*bom*/, "\r");
checkEncoding("UTF-16", false /*bom*/, "\r\n");
checkEncoding("UTF_16LE", false /*bom*/, "\r\n");
checkEncoding("UTF-16", true /*bom*/, "\r");
checkEncoding("UTF_16LE", true /*bom*/, "\r");
checkEncoding("UTF_32", true /*bom*/, "\r");
checkEncoding("UTF_32LE", true /*bom*/, "\r");
checkEncoding("UTF-16", true /*bom*/, "\r\n");
checkEncoding("UTF_16LE", true /*bom*/, "\r\n");
checkEncoding("UTF_32", true /*bom*/, "\r\n");
checkEncoding("UTF_32LE", true /*bom*/, "\r\n");
}
public void testGetLocaleAndRegion() throws Exception {
assertNull(getLocaleAndRegion(""));
assertNull(getLocaleAndRegion("values"));
assertNull(getLocaleAndRegion("values-xlarge-port"));
assertEquals("en", getLocaleAndRegion("values-en"));
assertEquals("pt-rPT", getLocaleAndRegion("values-pt-rPT-nokeys"));
assertEquals("zh-rCN", getLocaleAndRegion("values-zh-rCN-keyshidden"));
assertEquals("ms", getLocaleAndRegion("values-ms-keyshidden"));
}
public void testIsImported() throws Exception {
assertFalse(isImported(getCompilationUnit(
"package foo.bar;\n" +
"class Foo {\n" +
"}\n"),
"android.app.Activity"));
assertTrue(isImported(getCompilationUnit(
"package foo.bar;\n" +
"import foo.bar.*;\n" +
"import android.app.Activity;\n" +
"import foo.bar.Baz;\n" +
"class Foo {\n" +
"}\n"),
"android.app.Activity"));
assertTrue(isImported(getCompilationUnit(
"package foo.bar;\n" +
"import android.app.Activity;\n" +
"class Foo {\n" +
"}\n"),
"android.app.Activity"));
assertTrue(isImported(getCompilationUnit(
"package foo.bar;\n" +
"import android.app.*;\n" +
"class Foo {\n" +
"}\n"),
"android.app.Activity"));
assertFalse(isImported(getCompilationUnit(
"package foo.bar;\n" +
"import android.app.*;\n" +
"import foo.bar.Activity;\n" +
"class Foo {\n" +
"}\n"),
"android.app.Activity"));
}
private Node getCompilationUnit(String javaSource) {
IJavaParser parser = new LombokParser();
TestContext context = new TestContext(javaSource, new File("test"));
Node compilationUnit = parser.parseJava(context);
assertNotNull(javaSource, compilationUnit);
return compilationUnit;
}
private class TestContext extends JavaContext {
private final String mJavaSource;
public TestContext(String javaSource, File file) {
super(new LintDriver(new BuiltinIssueRegistry(),
new Main()), new Main().getProject(new File("dummy"), new File("dummy")),
null, file);
mJavaSource = javaSource;
}
@Override
@Nullable
public String getContents() {
return mJavaSource;
}
}
}