package kilim.test; import java.util.Arrays; import java.util.HashSet; import java.util.List; import junit.framework.TestCase; import kilim.analysis.ClassInfo; import kilim.tools.Javac; import kilim.tools.Weaver; public class TestDynamicWeaver extends TestCase { /** * Sample code to test a wide range of functionality: separate packages, import statements, * mutually recursive classes across packages, Pausable methods, inner classes, public * and non-public classes, etc. */ String code1 = "package code1;" + "import java.io.IOException;" + "import kilim.*;" + "public class A {" + " code2.B bar;" + " class Inner {" + " void foo() throws Pausable, IOException {" + " for (int i = 0; i < 10; i++) {" + " Outer.xxx();" + " }" + " }" + " }" + "}" + "class Outer { " + " static void xxx() throws Pausable, java.io.IOException {}" + "}"; String code2 = "package code2;" + "public class B { " + " code1.A foo;" + "}"; public List<ClassInfo> compile() throws Exception { List<ClassInfo> classes = Javac.compile(Arrays.asList(code1, code2)); assertTrue(classes.size() == 4); HashSet<String> expectedClasses = new HashSet<String>( Arrays.asList("code1.A", "code1.A$Inner", "code1.Outer", "code2.B")); for (ClassInfo cl : classes) { assertTrue(expectedClasses.contains(cl.className)); assertTrue(cl.bytes.length > 200); } return classes; } public void testWeave() throws Exception { List<ClassInfo> classes = compile(); classes = new Weaver().weave(classes); HashSet<String> expectedClasses = new HashSet<String>( Arrays.asList("kilim.S_I", "code1.A$Inner", "code1.Outer")); assertTrue(expectedClasses.size() == classes.size()); for (ClassInfo cl : classes) { assertTrue(expectedClasses.contains(cl.className)); assertTrue(cl.bytes != null && cl.bytes.length > 0); // ensure classes are loadable TestClassLoader cll = new TestClassLoader(); Class<?> c = null; try { c = cll.loadClass(cl.className); // The only class that should be loadable is "kilim.S_I" assertTrue(c.getName().startsWith("kilim")); } catch (ClassNotFoundException ignore) { // the new classes should not have been in the classpath, and // ClassNotFoundException is thrown as expected assertTrue(cl.className.startsWith("code")); // define these classes try { cll.load(cl); } catch (Throwable t) { fail(t.getMessage()); } } } } static class TestClassLoader extends ClassLoader { public void load(ClassInfo cl) { Class<?> c = super.defineClass(cl.className, cl.bytes, 0, cl.bytes.length); super.resolveClass(c); } } }