blob: b53c93c579e596e691791bf1058d31fa0216be7c [file] [log] [blame]
/*
* 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.manifmerger;
import com.android.SdkConstants;
import com.android.utils.ILogger;
import junit.framework.TestCase;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
/**
* Tests for the {@link com.android.manifmerger.PostValidator} class.
*/
public class PostValidatorTest extends TestCase {
@Mock
ILogger mILogger;
@Override
protected void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
}
public void testIncorrectRemove()
throws ParserConfigurationException, SAXException, IOException {
String main = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <activity android:name=\"activityOne\" tools:remove=\"exported\"/>\n"
+ "\n"
+ "</manifest>";
String library = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ "</manifest>";
XmlDocument mainDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(
getClass(), "testIncorrectRemoveMain"), main);
XmlDocument libraryDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(
getClass(), "testIncorrectRemoveLib"), library);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
mainDocument.merge(libraryDocument, mergingReportBuilder);
PostValidator.validate(mainDocument, mergingReportBuilder);
for (MergingReport.Record record : mergingReportBuilder.build().getLoggingRecords()) {
if (record.getSeverity() == MergingReport.Record.Severity.WARNING
&& record.toString().contains("PostValidatorTest#testIncorrectRemoveMain:8")) {
return;
}
}
fail("No reference to faulty PostValidatorTest#testIncorrectRemoveMain:8 found");
}
public void testIncorrectReplace()
throws ParserConfigurationException, SAXException, IOException {
String main = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <activity android:name=\"activityOne\" "
+ " android:exported=\"false\""
+ " tools:replace=\"exported\"/>\n"
+ "\n"
+ "</manifest>";
String library = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ "</manifest>";
XmlDocument mainDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(
getClass(), "testIncorrectReplaceMain"), main);
XmlDocument libraryDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(
getClass(), "testIncorrectReplaceLib"), library);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
mainDocument.merge(libraryDocument, mergingReportBuilder);
PostValidator.validate(mainDocument, mergingReportBuilder);
for (MergingReport.Record record : mergingReportBuilder.build().getLoggingRecords()) {
if (record.getSeverity() == MergingReport.Record.Severity.WARNING
&& record.toString().contains("PostValidatorTest#testIncorrectReplaceMain:8")) {
return;
}
}
fail("No reference to faulty PostValidatorTest#testIncorrectRemoveMain:8 found");
}
public void testApplicationInvalidOrder()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <uses-sdk minSdkVersion=\"14\"/>"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testApplicationInvalidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
// ensure application element is last.
Node lastChild = xmlDocument.getRootNode().getXml().getLastChild();
while(lastChild.getNodeType() != Node.ELEMENT_NODE) {
lastChild = lastChild.getPreviousSibling();
}
OrphanXmlElement xmlElement = new OrphanXmlElement((Element) lastChild);
assertEquals(ManifestModel.NodeTypes.APPLICATION, xmlElement.getType());
}
public void testApplicationInvalidOrder_withComments()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ " <!-- with comments ! -->"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <uses-sdk minSdkVersion=\"14\"/>"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testApplicationInvalidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
System.out.println(xmlDocument.prettyPrint());
// ensure application element is last.
Node lastChild = xmlDocument.getRootNode().getXml().getLastChild();
while(lastChild.getNodeType() != Node.ELEMENT_NODE) {
lastChild = lastChild.getPreviousSibling();
}
OrphanXmlElement xmlElement = new OrphanXmlElement((Element) lastChild);
assertEquals(ManifestModel.NodeTypes.APPLICATION, xmlElement.getType());
// check the comment was also moved.
assertEquals(Node.COMMENT_NODE, lastChild.getPreviousSibling().getNodeType());
}
public void testApplicationValidOrder()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ " <uses-sdk minSdkVersion=\"14\"/>"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testApplicationValidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
// ensure application element is last.
Node lastChild = xmlDocument.getRootNode().getXml().getLastChild();
while(lastChild.getNodeType() != Node.ELEMENT_NODE) {
lastChild = lastChild.getPreviousSibling();
}
OrphanXmlElement xmlElement = new OrphanXmlElement((Element) lastChild);
assertEquals(ManifestModel.NodeTypes.APPLICATION, xmlElement.getType());
}
public void testUsesSdkInvalidOrder()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <uses-sdk minSdkVersion=\"14\"/>"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testUsesSdkInvalidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
// ensure uses-sdk element is first.
Node firstChild = xmlDocument.getRootNode().getXml().getFirstChild();
while(firstChild.getNodeType() != Node.ELEMENT_NODE) {
firstChild = firstChild.getNextSibling();
}
OrphanXmlElement xmlElement = new OrphanXmlElement((Element) firstChild);
assertEquals(ManifestModel.NodeTypes.USES_SDK, xmlElement.getType());
}
public void testUsesSdkInvalidOrder_withComments()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ " <!-- with comments ! -->"
+ " <uses-sdk minSdkVersion=\"14\"/>"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testUsesSdkInvalidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
System.out.println(xmlDocument.prettyPrint());
// ensure uses-sdk element is first.
Node firstChild = xmlDocument.getRootNode().getXml().getFirstChild();
while(firstChild.getNodeType() != Node.ELEMENT_NODE) {
firstChild = firstChild.getNextSibling();
}
OrphanXmlElement xmlElement = new OrphanXmlElement((Element) firstChild);
assertEquals(ManifestModel.NodeTypes.USES_SDK, xmlElement.getType());
// check the comment was also moved.
assertEquals(Node.COMMENT_NODE, firstChild.getPreviousSibling().getNodeType());
}
public void testUsesSdkValidOrder()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <uses-sdk minSdkVersion=\"14\"/>"
+ "\n"
+ " <activity android:name=\"activityOne\"/>"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testUsesSdkValidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
// ensure uses-sdk element is first.
Node firstChild = xmlDocument.getRootNode().getXml().getFirstChild();
while(firstChild.getNodeType() != Node.ELEMENT_NODE) {
firstChild = firstChild.getNextSibling();
}
OrphanXmlElement xmlElement = new OrphanXmlElement((Element) firstChild);
assertEquals(ManifestModel.NodeTypes.USES_SDK, xmlElement.getType());
}
public void testAndroidNamespacePresence()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <uses-sdk minSdkVersion=\"14\"/>"
+ "\n"
+ " <application android:label=\"@string/lib_name\" />\n"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testApplicationInvalidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
// ensure application element is last.
String attribute = xmlDocument.getRootNode().getXml().getAttribute("xmlns:android");
assertEquals(SdkConstants.ANDROID_URI, attribute);
}
public void testAndroidNamespacePresence_differentPrefix()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " xmlns:A=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\"\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <uses-sdk A:minSdkVersion=\"14\"/>"
+ "\n"
+ " <application A:label=\"@string/lib_name\" />\n"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testApplicationInvalidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
// ensure application element is last.
String attribute = xmlDocument.getRootNode().getXml().getAttribute("xmlns:A");
assertEquals(SdkConstants.ANDROID_URI, attribute);
}
public void testAndroidNamespaceAbsence()
throws ParserConfigurationException, SAXException, IOException {
String input = ""
+ "<manifest\n"
+ " package=\"com.example.lib3\">\n"
+ "\n"
+ " <application />\n"
+ "\n"
+ "</manifest>";
XmlDocument xmlDocument = TestUtils.xmlDocumentFromString(
new TestUtils.TestSourceLocation(getClass(), "testApplicationInvalidOrder"), input);
MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mILogger);
PostValidator.validate(xmlDocument, mergingReportBuilder);
// ensure application element is last.
String attribute = xmlDocument.getRootNode().getXml().getAttribute("xmlns:android");
assertEquals(SdkConstants.ANDROID_URI, attribute);
}
}