Added more tests and made them runnable with surefire

This commit is contained in:
Sander Hautvast 2020-11-11 10:58:39 +01:00
parent e2c874937c
commit 72ef703e40
15 changed files with 247 additions and 35 deletions

View file

@ -13,6 +13,10 @@ public class ConstantPoolCreator {
private int index; // the current index that will be assigned to a constant pool entry. It needs to be unique for each entry. private int index; // the current index that will be assigned to a constant pool entry. It needs to be unique for each entry.
// References to other elements in the pool are made through indexes, so they have to be valid to guarantee that the class can be loaded by the JVM. // References to other elements in the pool are made through indexes, so they have to be valid to guarantee that the class can be loaded by the JVM.
public static ConstantPool create(Set<ConstantPoolEntry> constantTree){
return new ConstantPoolCreator().createConstantPool(constantTree);
}
public ConstantPool createConstantPool(Set<ConstantPoolEntry> constantTree) { public ConstantPool createConstantPool(Set<ConstantPoolEntry> constantTree) {
constantPool = new ConstantPool(); constantPool = new ConstantPool();
index = 0; index = 0;

View file

@ -17,11 +17,19 @@ public class TypeMapper {
MAP.put(short.class, "S"); MAP.put(short.class, "S");
MAP.put(boolean.class, "Z"); MAP.put(boolean.class, "Z");
} }
//TODO something with arrays //TODO something with arrays
public static String map(Class<?> type) { public static String map(Class<?> type) {
return Optional.ofNullable(MAP.get(type)) return Optional.ofNullable(MAP.get(type)).orElseGet(() -> {
.orElseThrow(() -> new RuntimeException("Type " + type.getName() + " not found")); if (type.isArray()) {
return internalName(type.getName());
} else {
return "L" + internalName(type.getName());
}
});
} }
private static String internalName(String name) {
return name.replaceAll("\\.", "/");
}
} }

View file

@ -17,7 +17,7 @@ public class ClassEntry extends ConstantPoolEntry {
@Override @Override
public String toString() { public String toString() {
return "Class\t\t#" + getNameIndex() + "\t\t// " + name.getUtf8(); return "Class\t\t\t#" + getNameIndex() + "\t\t// " + name.getUtf8();
} }
@Override @Override

View file

@ -24,8 +24,8 @@ public class FieldRefEntry extends ConstantPoolEntry {
@Override @Override
public String toString() { public String toString() {
return "FieldRef\t#" + getClassIndex() + return "FieldRef\t\t#" + getClassIndex() +
".#=" + getNameAndTypeIndex() +"\t// "+classEntry.getName()+'.'+nameAndTypeEntry.toString(); ".#=" + getNameAndTypeIndex() + "\t// " + classEntry.getName() + '.' + nameAndTypeEntry.getName() + ':' + nameAndTypeEntry.getType();
} }

View file

@ -15,8 +15,13 @@ public class CompilerTests {
// creates simplest class possible and checks the tree, that the ConstantTreeCreator emits // creates simplest class possible and checks the tree, that the ConstantTreeCreator emits
@Test // This is not a maintainable test @Test // This is not a maintainable test
public void testMethodRefEntryForSuperConstructor() { public void testMethodRefEntryForSuperConstructor() {
// Arrange
BeeClass classWithIntField = TestData.emptyClass(); BeeClass classWithIntField = TestData.emptyClass();
// Act
CompiledClass compiledClass = Compiler.compile(classWithIntField); CompiledClass compiledClass = Compiler.compile(classWithIntField);
// Assert
Set<ConstantPoolEntry> constantTree = compiledClass.getConstantTree(); Set<ConstantPoolEntry> constantTree = compiledClass.getConstantTree();
assertEquals(2, constantTree.size()); assertEquals(2, constantTree.size());
ConstantPoolEntry superConstructor = constantTree.iterator().next(); ConstantPoolEntry superConstructor = constantTree.iterator().next();

View file

@ -1,13 +1,32 @@
package nl.sander.beejava; package nl.sander.beejava;
import nl.sander.beejava.api.BeeClass; import nl.sander.beejava.api.BeeClass;
import nl.sander.beejava.constantpool.ConstantPool;
import nl.sander.beejava.constantpool.entry.ClassEntry;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ConstantPoolUniquenessTests { public class ConstantPoolUniquenessTests {
@Test @Test
public void test() { public void test() {
// Arrange
BeeClass someClass = TestData.createClassWithTwoReferencesToSomeClass(); BeeClass someClass = TestData.createClassWithTwoReferencesToSomeClass();
// Act
CompiledClass compiledClass = Compiler.compile(someClass); CompiledClass compiledClass = Compiler.compile(someClass);
BytecodeGenerator.generate(compiledClass); ConstantPool constantPool = new ConstantPoolCreator().createConstantPool(compiledClass.getConstantTree());
// Assert
List<ClassEntry> refsToSystem = constantPool.stream()
.filter(cpe -> cpe instanceof ClassEntry)
.map(cpe -> (ClassEntry) cpe)
.filter(ce -> ce.getName().equals("java/lang/System"))
.collect(Collectors.toList());
assertEquals(1, refsToSystem.size());
} }
} }

View file

@ -44,34 +44,43 @@ public class TestData {
line(3, RETURN)) line(3, RETURN))
.build(); .build();
BeeMethod print2 = BeeMethod.builder()
.withAccessFlags(MethodAccessFlag.PUBLIC)
.withCode(
line(0, GET, "java.lang.System","out"),
line(1, LD_CONST, "2"),
line(2, INVOKE, "java.io.PrintStream", "println", "(java.lang.String)"),
line(3, RETURN))
.build();
return BeeClass.builder() return BeeClass.builder()
.withClassFileVersion(Version.V14) .withClassFileVersion(Version.V14)
.withPackage("nl.sander.beejava.test") .withPackage("nl.sander.beejava.test")
.withAccessFlags(PUBLIC) .withAccessFlags(PUBLIC)
.withSimpleName("ClassWithReferences") .withSimpleName("ClassWithReferences")
.withConstructors(createConstructor()) // There's no default constructor in beejava. The user must always add them .withConstructors(createConstructor()) // There's no default constructor in beejava. The user must always add them
.withMethods(print1) .withMethods(print1, print2)
.build(); .build();
} }
public static BeeClass createClassWithIntField() { public static BeeClass createClassWithField(Class<?> fieldType) {
BeeField intField = BeeField.builder() BeeField field = BeeField.builder()
.withAccessFlags(FieldAccessFlag.PRIVATE) .withAccessFlags(FieldAccessFlag.PRIVATE)
.withType(int.class) .withType(fieldType)
.withName("intField") .withName("field")
.build(); .build();
BeeParameter intValueParameter = BeeParameter.create(int.class, "intValue"); BeeParameter parameter = BeeParameter.create(fieldType, "value");
BeeConstructor constructor = BeeConstructor.builder() BeeConstructor constructor = BeeConstructor.builder()
.withAccessFlags(MethodAccessFlag.PUBLIC) .withAccessFlags(MethodAccessFlag.PUBLIC)
.withFormalParameters(intValueParameter) .withFormalParameters(parameter)
.withCode( .withCode(
line(0, LD_VAR, Ref.THIS), line(0, LD_VAR, Ref.THIS),
line(1, INVOKE, Ref.SUPER, "<init>", "()"), line(1, INVOKE, Ref.SUPER, "<init>", "()"),
line(2, LD_VAR, Ref.THIS), line(2, LD_VAR, Ref.THIS),
line(3, LD_VAR, intValueParameter), line(3, LD_VAR, parameter),
line(4, PUT, intField), line(4, PUT, field),
line(5, RETURN)) line(5, RETURN))
.build(); .build();
@ -79,9 +88,9 @@ public class TestData {
.withClassFileVersion(Version.V14) .withClassFileVersion(Version.V14)
.withPackage("nl.sander.beejava.test") .withPackage("nl.sander.beejava.test")
.withAccessFlags(PUBLIC) .withAccessFlags(PUBLIC)
.withSimpleName("IntBean") .withSimpleName("Bean")
.withSuperClass(Object.class) .withSuperClass(Object.class)
.withFields(intField) .withFields(field)
.withConstructors(constructor) .withConstructors(constructor)
.build(); .build();
} }

View file

@ -0,0 +1,168 @@
package nl.sander.beejava;
import nl.sander.beejava.api.BeeClass;
import nl.sander.beejava.constantpool.ConstantPool;
import nl.sander.beejava.constantpool.entry.NameAndTypeEntry;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class TypeMapperTest {
@Test
public void test_int() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(int.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("I", fieldEntry.getType());
}
@Test
public void test_double() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(double.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("D", fieldEntry.getType());
}
@Test
public void test_float() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(float.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("F", fieldEntry.getType());
}
@Test
public void test_byte() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(byte.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("B", fieldEntry.getType());
}
@Test
public void test_short() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(short.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("S", fieldEntry.getType());
}
@Test
public void test_long() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(long.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("J", fieldEntry.getType());
}
@Test
public void test_char() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(char.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("C", fieldEntry.getType());
}
@Test
public void test_boolean() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(boolean.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("Z", fieldEntry.getType());
}
@Test
public void test_Object() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(Object.class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("Ljava/lang/Object", fieldEntry.getType());
}
@Test
public void test_int_array() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(int[].class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("[I", fieldEntry.getType());
}
@Test
public void test_Object_array() {
// Arrange
BeeClass beeClass = TestData.createClassWithField(String[].class);
// Act
ConstantPool constantPool = createConstantPool(beeClass);
// Assert
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
assertEquals("[Ljava/lang/String;", fieldEntry.getType());
}
private ConstantPool createConstantPool(BeeClass beeClass) {
CompiledClass compiledClass = Compiler.compile(beeClass);
return ConstantPoolCreator.create(compiledClass.getConstantTree());
}
private NameAndTypeEntry getFieldNameAndType(ConstantPool constantPool) {
return constantPool.stream()
.filter(cpe -> cpe instanceof NameAndTypeEntry)
.map(NameAndTypeEntry.class::cast)
.filter(nate -> nate.getName().equals("field"))
.findAny().orElseGet(() -> fail("'field' not found"));
}
}

View file

@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertSame;
public class ClassEntryTest { public class ClassEntryTest {
@Test @Test
public void testGetChildren() { public void test_GetChildren() {
Utf8Entry name = new Utf8Entry(""); Utf8Entry name = new Utf8Entry("");
assertSame(new ClassEntry(name).getChildren().iterator().next(), name); assertSame(new ClassEntry(name).getChildren().iterator().next(), name);
} }

View file

@ -14,19 +14,19 @@ public class ConstantPoolEntryTest {
}; };
@Test @Test
public void getSetIndex() { public void test_getSetIndex() {
int value = 2; int value = 2;
entry.setIndex(value); entry.setIndex(value);
assertEquals(value, entry.getIndex()); assertEquals(value, entry.getIndex());
} }
@Test @Test
public void lowerByte() { public void test_lowerByte() {
assertEquals(1, entry.lowerByte(257)); assertEquals(1, entry.lowerByte(257));
} }
@Test @Test
public void upperByte() { public void test_upperByte() {
assertEquals(1, entry.upperByte(257)); assertEquals(1, entry.upperByte(257));
} }
} }

View file

@ -4,10 +4,10 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
class DoubleEntryTest { public class DoubleEntryTest {
@Test @Test
void getBytes() { public void test_getBytes() {
assertArrayEquals(new byte[]{6, 64, 40, 0, 0, 0, 0, 0, 0}, new DoubleEntry(12D).getBytes()); assertArrayEquals(new byte[]{6, 64, 40, 0, 0, 0, 0, 0, 0}, new DoubleEntry(12D).getBytes());
} }
} }

View file

@ -4,10 +4,10 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
class FloatEntryTest { public class FloatEntryTest {
@Test @Test
void getBytes() { public void test_getBytes() {
assertArrayEquals(new byte[]{4, 0, 0, 0, 0}, new FloatEntry(0F).getBytes()); assertArrayEquals(new byte[]{4, 0, 0, 0, 0}, new FloatEntry(0F).getBytes());
} }
} }

View file

@ -4,10 +4,10 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
class IntegerEntryTest { public class IntegerEntryTest {
@Test @Test
void getBytes() { public void test_getBytes() {
assertArrayEquals(new byte[]{3, 18, 52, 86, 120}, new IntegerEntry(0x12345678).getBytes()); assertArrayEquals(new byte[]{3, 18, 52, 86, 120}, new IntegerEntry(0x12345678).getBytes());
} }
} }

View file

@ -4,10 +4,10 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
class LongEntryTest { public class LongEntryTest {
@Test @Test
void getBytes() { public void test_getBytes() {
assertArrayEquals(new byte[]{5, 18, 52, 86, 120, -102, -68, -34, -16}, new LongEntry(0x123456789ABCDEF0L).getBytes()); assertArrayEquals(new byte[]{5, 18, 52, 86, 120, -102, -68, -34, -16}, new LongEntry(0x123456789ABCDEF0L).getBytes());
} }
} }

View file

@ -1,6 +1,5 @@
package nl.sander.beejava.flags; package nl.sander.beejava.flags;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Arrays; import java.util.Arrays;
@ -10,12 +9,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class ClassAccessFlagTest { public class ClassAccessFlagTest {
@Test @Test
public void mustOr1Value() { public void test_mustOr1Value() {
assertEquals(1, ClassAccessFlag.getSum(Collections.singletonList(ClassAccessFlag.PUBLIC))); assertEquals(1, ClassAccessFlag.getSum(Collections.singletonList(ClassAccessFlag.PUBLIC)));
} }
@Test @Test
public void mustOr2Values() { public void test_mustOr2Values() {
assertEquals(17, ClassAccessFlag.getSum(Arrays.asList(ClassAccessFlag.PUBLIC, ClassAccessFlag.FINAL))); assertEquals(17, ClassAccessFlag.getSum(Arrays.asList(ClassAccessFlag.PUBLIC, ClassAccessFlag.FINAL)));
} }