am 0cef5c46: Merge change 21056 into donut
Merge commit '0cef5c4666b9c77161421c8a52b7dddff42f12da' into eclair * commit '0cef5c4666b9c77161421c8a52b7dddff42f12da': Add a functional test that renders all the layouts of ApiDemos
This commit is contained in:
@@ -6,5 +6,6 @@
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
|
||||
<classpathentry kind="lib" path="/adt/sdklib.jar" sourcepath="/SdkLib"/>
|
||||
<classpathentry kind="lib" path="/adt/layoutlib_api.jar" sourcepath="/layoutlib_api"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -16,4 +16,6 @@ Require-Bundle: org.eclipse.ui,
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Vendor: The Android Open Source Project
|
||||
Bundle-ClassPath: kxml2-2.3.0.jar,
|
||||
.
|
||||
.,
|
||||
layoutlib_api.jar,
|
||||
sdklib.jar
|
||||
|
||||
@@ -7,4 +7,6 @@ bin.includes = META-INF/,\
|
||||
prefs.template,\
|
||||
unittest.xml,\
|
||||
kxml2-2.3.0.jar,\
|
||||
unittests/data/
|
||||
unittests/data/,\
|
||||
sdklib.jar,\
|
||||
layoutlib_api.jar
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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
|
||||
@@ -18,7 +18,7 @@ package com.android.ide.eclipse.tests;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Generic superclass for Eclipse Android functional test cases, that provides
|
||||
* Generic superclass for Eclipse Android functional test cases, that provides
|
||||
* common facilities
|
||||
*/
|
||||
public class FuncTestCase extends TestCase {
|
||||
@@ -27,12 +27,15 @@ public class FuncTestCase extends TestCase {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* @throws IllegalArgumentException if environment variable "sdk_home" is
|
||||
* not set
|
||||
*/
|
||||
protected FuncTestCase() {
|
||||
mOsSdkLocation = System.getProperty("sdk_home");
|
||||
if (mOsSdkLocation == null) {
|
||||
mOsSdkLocation = System.getenv("sdk_home");
|
||||
}
|
||||
if (mOsSdkLocation == null || mOsSdkLocation.length() < 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Environment variable sdk_home is not set");
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.ide.eclipse.tests;
|
||||
|
||||
import com.android.ide.eclipse.tests.functests.layoutRendering.ApiDemosRenderingTest;
|
||||
import com.android.ide.eclipse.tests.functests.sampleProjects.SampleProjectTest;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
@@ -28,18 +29,19 @@ public class FuncTests extends TestSuite {
|
||||
static final String FUNC_TEST_PACKAGE = "com.android.ide.eclipse.tests.functests";
|
||||
|
||||
public FuncTests() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a suite of test cases to be run.
|
||||
* Needed for JUnit3 compliant command line test runner
|
||||
*/
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite();
|
||||
|
||||
|
||||
suite.addTestSuite(SampleProjectTest.class);
|
||||
|
||||
suite.addTestSuite(ApiDemosRenderingTest.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.tests.functests.layoutRendering;
|
||||
|
||||
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
|
||||
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
|
||||
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
|
||||
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
|
||||
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
|
||||
import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
|
||||
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
|
||||
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
|
||||
import com.android.ide.eclipse.tests.FuncTestCase;
|
||||
import com.android.layoutlib.api.ILayoutResult;
|
||||
import com.android.layoutlib.api.IProjectCallback;
|
||||
import com.android.layoutlib.api.IResourceValue;
|
||||
import com.android.layoutlib.api.IXmlPullParser;
|
||||
import com.android.sdklib.IAndroidTarget;
|
||||
import com.android.sdklib.SdkConstants;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.kxml2.io.KXmlParser;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class ApiDemosRenderingTest extends FuncTestCase {
|
||||
|
||||
/**
|
||||
* Custom parser that implements {@link IXmlPullParser} (which itself extends
|
||||
* {@link XmlPullParser}).
|
||||
*/
|
||||
private final static class TestParser extends KXmlParser implements IXmlPullParser {
|
||||
/**
|
||||
* Since we're not going to go through the result of the rendering/layout, we can return
|
||||
* null for the View Key.
|
||||
*/
|
||||
public Object getViewKey() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final static class ProjectCallBack implements IProjectCallback {
|
||||
// resource id counter.
|
||||
// We start at 0x7f000000 to avoid colliding with the framework id
|
||||
// since we have no access to the project R.java and we need to generate them automatically.
|
||||
private int mIdCounter = 0x7f000000;
|
||||
|
||||
// in some cases, the id that getResourceValue(String type, String name) returns
|
||||
// will be sent back to get the type/name. This map stores the id/type/name we generate
|
||||
// to be able to do the reverse resolution.
|
||||
private Map<Integer, String[]> mResourceMap = new HashMap<Integer, String[]>();
|
||||
|
||||
private boolean mCustomViewAttempt = false;
|
||||
|
||||
public String getNamespace() {
|
||||
// TODO: read from the ApiDemos manifest.
|
||||
return "com.example.android.apis";
|
||||
}
|
||||
|
||||
public Integer getResourceValue(String type, String name) {
|
||||
Integer result = ++mIdCounter;
|
||||
mResourceMap.put(result, new String[] { name, type });
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
|
||||
throws ClassNotFoundException, Exception {
|
||||
mCustomViewAttempt = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
public String[] resolveResourceValue(int id) {
|
||||
return mResourceMap.get(id);
|
||||
}
|
||||
|
||||
public String resolveResourceValue(int[] id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Sdk mSdk;
|
||||
|
||||
public void testApiDemos() throws IOException, XmlPullParserException {
|
||||
loadSdk();
|
||||
findApiDemos();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the {@link Sdk}.
|
||||
*/
|
||||
private void loadSdk() {
|
||||
mSdk = Sdk.loadSdk(this.getOsSdkLocation());
|
||||
|
||||
int n = mSdk.getTargets().length;
|
||||
if (n > 0) {
|
||||
for (IAndroidTarget target : mSdk.getTargets()) {
|
||||
IStatus status = new AndroidTargetParser(target).run(new NullProgressMonitor());
|
||||
if (status.getCode() != IStatus.OK) {
|
||||
fail("Failed to parse targets data");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void findApiDemos() throws IOException, XmlPullParserException {
|
||||
IAndroidTarget[] targets = mSdk.getTargets();
|
||||
|
||||
for (IAndroidTarget target : targets) {
|
||||
String path = target.getPath(IAndroidTarget.SAMPLES);
|
||||
File samples = new File(path);
|
||||
if (samples.isDirectory()) {
|
||||
File[] files = samples.listFiles();
|
||||
for (File file : files) {
|
||||
if ("apidemos".equalsIgnoreCase(file.getName())) {
|
||||
testSample(target, file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fail("Failed to find ApiDemos!");
|
||||
}
|
||||
|
||||
private void testSample(IAndroidTarget target, File sampleProject) throws IOException, XmlPullParserException {
|
||||
AndroidTargetData data = mSdk.getTargetData(target);
|
||||
if (data == null) {
|
||||
fail("No AndroidData!");
|
||||
}
|
||||
|
||||
LayoutBridge bridge = data.getLayoutBridge();
|
||||
if (bridge.status != LoadStatus.LOADED || bridge.bridge == null) {
|
||||
fail("Fail to load the bridge");
|
||||
}
|
||||
|
||||
File resFolder = new File(sampleProject, SdkConstants.FD_RES);
|
||||
if (resFolder.isDirectory() == false) {
|
||||
fail("Sample project has no res folder!");
|
||||
}
|
||||
|
||||
// look for the layout folder
|
||||
File layoutFolder = new File(resFolder, SdkConstants.FD_LAYOUT);
|
||||
if (layoutFolder.isDirectory() == false) {
|
||||
fail("Sample project has no layout folder!");
|
||||
}
|
||||
|
||||
// first load the project's target framework resource
|
||||
ProjectResources framework = ResourceManager.getInstance().loadFrameworkResources(target);
|
||||
|
||||
// now load the project resources
|
||||
ProjectResources project = new ProjectResources(false /* isFrameworkRepository */);
|
||||
ResourceManager.getInstance().loadResources(project, resFolder);
|
||||
|
||||
|
||||
// Create a folder configuration that will be used for the rendering:
|
||||
FolderConfiguration config = getConfiguration();
|
||||
|
||||
// get the configured resources
|
||||
Map<String, Map<String, IResourceValue>> configuredFramework =
|
||||
framework.getConfiguredResources(config);
|
||||
Map<String, Map<String, IResourceValue>> configuredProject =
|
||||
project.getConfiguredResources(config);
|
||||
|
||||
boolean saveFiles = System.getenv("save_file") != null;
|
||||
|
||||
// loop on the layouts and render them
|
||||
File[] layouts = layoutFolder.listFiles();
|
||||
for (File layout : layouts) {
|
||||
// create a parser for the layout file
|
||||
TestParser parser = new TestParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||
parser.setInput(new FileReader(layout));
|
||||
|
||||
System.out.println("Rendering " + layout.getName());
|
||||
|
||||
ProjectCallBack projectCallBack = new ProjectCallBack();
|
||||
|
||||
ILayoutResult result = bridge.bridge.computeLayout(
|
||||
parser,
|
||||
null /*projectKey*/,
|
||||
320,
|
||||
480,
|
||||
160, //density
|
||||
160, //xdpi
|
||||
160, // ydpi
|
||||
"Theme", //themeName
|
||||
false, //isProjectTheme
|
||||
configuredProject,
|
||||
configuredFramework,
|
||||
projectCallBack,
|
||||
null //logger
|
||||
);
|
||||
|
||||
if (result.getSuccess() != ILayoutResult.SUCCESS) {
|
||||
if (projectCallBack.mCustomViewAttempt == false) {
|
||||
System.out.println("FAILED");
|
||||
fail(String.format("Rendering %1$s: %2$s", layout.getName(),
|
||||
result.getErrorMessage()));
|
||||
} else {
|
||||
System.out.println("Ignore custom views for now");
|
||||
}
|
||||
} else {
|
||||
if (saveFiles) {
|
||||
File tmp = File.createTempFile(layout.getName(), ".png");
|
||||
ImageIO.write(result.getImage(), "png", tmp);
|
||||
}
|
||||
System.out.println("Success!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FolderConfiguration getConfiguration() {
|
||||
FolderConfiguration config = new FolderConfiguration();
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user