Commit 49c5ceb0 authored by Skylot's avatar Skylot

core: add framework for internal tests

parent 4c03a424
......@@ -191,4 +191,8 @@ public final class Decompiler {
LOG.error("Process class error", e);
}
}
RootNode getRoot() {
return root;
}
}
package jadx.api;
import jadx.core.Jadx;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.visitors.DepthTraverser;
import jadx.core.dex.visitors.IDexTreeVisitor;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
public abstract class InternalJadxTest {
public ClassNode getClassNode(Class clazz) {
try {
File temp = getJarForClass(clazz);
Decompiler d = new Decompiler();
try {
d.loadFile(temp);
assertEquals(d.getClasses().size(), 1);
} catch (Exception e) {
fail(e.getMessage());
} finally {
temp.delete();
}
List<ClassNode> classes = d.getRoot().getClasses(false);
ClassNode cls = classes.get(0);
assertEquals(cls.getFullName(), clazz.getName());
cls.load();
List<IDexTreeVisitor> passes = Jadx.getPassesList(new DefaultJadxArgs(), null);
for (IDexTreeVisitor visitor : passes) {
DepthTraverser.visit(visitor, cls);
}
return cls;
} catch (Exception e) {
fail(e.getMessage());
return null;
}
}
protected MethodNode getMethod(ClassNode cls, String method) {
for (MethodNode mth : cls.getMethods()) {
if (mth.getName().equals(method)) {
return mth;
}
}
fail("Method not found " + method + " in class " + cls);
return null;
}
public File getJarForClass(Class<?> cls) throws IOException {
File classFile = getClassFile(cls);
String shortClsFileName = cls.getName().replace('.', '/') + ".class";
File temp = File.createTempFile("jadx-tmp-", System.nanoTime() + ".jar");
JarOutputStream jo = new JarOutputStream(new FileOutputStream(temp));
add(classFile, shortClsFileName, jo);
jo.close();
temp.deleteOnExit();
return temp;
}
private File getClassFile(Class<?> cls) {
String path = cutPackage(cls) + ".class";
URL resource = cls.getResource(path);
if (resource == null) {
throw new AssertionError("Class file not found: " + path);
}
if (!"file".equalsIgnoreCase(resource.getProtocol())) {
throw new IllegalStateException("Class is not stored in a file.");
}
return new File(resource.getPath());
}
private String cutPackage(Class<?> cls) {
String longName = cls.getName();
String pkg = cls.getPackage().getName();
return longName.substring(pkg.length() + 1, longName.length());
}
private void add(File source, String entryName, JarOutputStream target) throws IOException {
BufferedInputStream in = null;
try {
JarEntry entry = new JarEntry(entryName);
entry.setTime(source.lastModified());
target.putNextEntry(entry);
in = new BufferedInputStream(new FileInputStream(source));
byte[] buffer = new byte[1024];
while (true) {
int count = in.read(buffer);
if (count == -1)
break;
target.write(buffer, 0, count);
}
target.closeEntry();
} finally {
if (in != null)
in.close();
}
}
}
package jadx.api;
import jadx.core.dex.instructions.ArithNode;
import jadx.core.dex.instructions.ArithOp;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import java.util.List;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
public class TestFieldIncrement extends InternalJadxTest {
public static class TestCls {
public int field = 1;
public void method() {
field++;
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
MethodNode mth = getMethod(cls, "method");
List<InsnNode> insns = mth.getBasicBlocks().get(0).getInstructions();
assertEquals(insns.size(), 1);
InsnNode insnNode = insns.get(0);
assertEquals(InsnType.ARITH, insnNode.getType());
assertEquals(ArithOp.ADD, ((ArithNode) insnNode).getOp());
assertThat(cls.getCode().toString(), containsString("field++;"));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment