/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.classloader; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import org.jikesrvm.VM; import org.jikesrvm.junit.runners.RequiresBuiltJikesRVM; import org.jikesrvm.junit.runners.VMRequirements; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(VMRequirements.class) @Category(RequiresBuiltJikesRVM.class) public class MethodVectorTest { private static TypeReference tRef; private MethodVector mv; @BeforeClass public static void createTypeReference() { if (VM.runningVM) { tRef = TypeReference.findOrCreate("LFoo;"); } } @Before public void setUp() { mv = new MethodVector(); } @Test public void oneMethodIsSavedCorrectly() { RVMMethod oneMethod = createMockMethod("foo"); mv.addElement(oneMethod); RVMMethod[] methods = mv.finish(); assertThat(methods.length, is(1)); assertSame(methods[0], oneMethod); } RVMMethod createMockMethod(String methodName) { Atom memberName = Atom.findOrCreateAsciiAtom(methodName); Atom memberDescriptor = Atom.findOrCreateAsciiAtom("()V"); MemberReference mr = MemberReference.findOrCreate(tRef, memberName, memberDescriptor); short mo = 0; short lw = 0; short ow = 0; byte[] bc = new byte[0]; int[] constantPool = new int[0]; NormalMethod mockMethod = new NormalMethod(tRef, mr, mo, null, lw, ow, bc, null, null, null, constantPool, null, null, null, null); return mockMethod; } @Test public void finalArrayIsTrimmedToSize() { RVMMethod fooMethod = createMockMethod("foo"); RVMMethod barMethod = createMockMethod("bar"); RVMMethod bazMethod = createMockMethod("baz"); mv.addElement(fooMethod); mv.addElement(barMethod); mv.addElement(bazMethod); RVMMethod[] methods = mv.finish(); assertThat(methods.length, is(3)); List<RVMMethod> methodList = Arrays.asList(methods); assertTrue(methodList.contains(fooMethod)); assertTrue(methodList.contains(barMethod)); assertTrue(methodList.contains(bazMethod)); } @Test public void addUniqueElementOnlyAddsElementsIfRequired() { RVMMethod testMethod = createMockMethod("test"); mv.addUniqueElement(testMethod); mv.addUniqueElement(testMethod); RVMMethod[] methods = mv.finish(); assertThat(methods.length, is(1)); assertSame(methods[0], testMethod); } @Test public void sizeWorksCorrectly() { assertThat(mv.size(), is(0)); RVMMethod testMethod = createMockMethod("sizeTest"); mv.addElement(testMethod); assertThat(mv.size(), is(1)); mv.addElement(testMethod); assertThat(mv.size(), is(2)); } @Test public void elementAtWorksForValidIndexes() { RVMMethod fooMethod = createMockMethod("foo"); mv.addElement(fooMethod); RVMMethod barMethod = createMockMethod("bar"); mv.addElement(barMethod); RVMMethod bazMethod = createMockMethod("baz"); mv.addElement(bazMethod); assertSame(fooMethod, mv.elementAt(0)); assertSame(barMethod, mv.elementAt(1)); assertSame(bazMethod, mv.elementAt(2)); } @Test(expected = ArrayIndexOutOfBoundsException.class) public void elementAtDoesNotCheckForTooSmallIndexes() { mv.elementAt(-1); } @Test(expected = ArrayIndexOutOfBoundsException.class) public void elementAtDoesNotCheckForTooBigIndexes() { mv.elementAt(1000); } @Test public void elementAtReturnsUnintializedValuesForInvalidIndexes() { RVMMethod method = mv.elementAt(5); assertNull(method); } @Test public void setElementWorksCorrectly() throws Exception { RVMMethod fooMethod = createMockMethod("foo"); RVMMethod barMethod = createMockMethod("bar"); RVMMethod bazMethod = createMockMethod("baz"); RVMMethod replaceMethod = createMockMethod("replace"); mv.addElement(fooMethod); mv.addElement(barMethod); mv.addElement(bazMethod); mv.setElementAt(replaceMethod, 1); RVMMethod[] methods = mv.finish(); assertThat(methods.length, is(3)); assertSame(fooMethod, methods[0]); assertSame(replaceMethod, methods[1]); assertSame(bazMethod, methods[2]); } @Test(expected = ArrayIndexOutOfBoundsException.class) public void setElementAtDoesNotCheckForTooSmallIndexes() { RVMMethod indexTooSmallMethod = createMockMethod("indexTooSmall"); mv.setElementAt(indexTooSmallMethod, -1); } @Test(expected = ArrayIndexOutOfBoundsException.class) public void setElementAtDoesNotCheckForTooBigIndexes() { RVMMethod indexTooBigMethod = createMockMethod("indexTooBig"); mv.setElementAt(indexTooBigMethod, 1000); } @Test public void setElementAtAllowsSettingOfValuesForInvalidIndexes() { RVMMethod invalidIndexMethod = createMockMethod("invalidIndex"); mv.setElementAt(invalidIndexMethod, 5); } @Test(expected = NullPointerException.class) public void setElementAtAllowsNullValuesWhichWillCauseTroubleLater() { RVMMethod okMethod = createMockMethod("ok"); mv.addElement(okMethod); mv.setElementAt(null, 0); RVMMethod[] methods = mv.finish(); assertNull(methods[0]); } @Test public void cachingWorks() throws Exception { RVMMethod methodOne = createMockMethod("methodOne"); RVMMethod methodTwo = createMockMethod("methodTwo"); mv.addElement(methodOne); mv.addElement(methodTwo); RVMMethod[] canonicalMethodArray = mv.finish(); MethodVector anotherVectorWithSameFields = new MethodVector(); anotherVectorWithSameFields.addElement(methodOne); anotherVectorWithSameFields.addElement(methodTwo); RVMMethod[] resultMethodArray = anotherVectorWithSameFields.finish(); assertSame(canonicalMethodArray, resultMethodArray); } }