text: package rocks.inspectit.shared.all.instrumentation.classcache;
  
  import static org.hamcrest.MatcherAssert.assertThat;
  import static org.hamcrest.Matchers.contains;
  import static org.hamcrest.Matchers.empty;
  import static org.hamcrest.Matchers.equalTo;
  import static org.hamcrest.Matchers.hasItem;
  import static org.hamcrest.Matchers.hasSize;
  import static org.hamcrest.Matchers.is;
  
  import java.util.Collection;
  
  import org.testng.annotations.Test;
  
  import nl.jqno.equalsverifier.EqualsVerifier;
  import rocks.inspectit.shared.all.instrumentation.config.impl.MethodInstrumentationConfig;
  
  @SuppressWarnings("PMD")
  public class ClassTypeTest {
  
  	ClassType test;
  
  	@Test
  	public void equalsContract() {
  		// note that we add state to the type so super.equals(InterfaceType) should return false
  		EqualsVerifier.forClass(ClassType.class).usingGetClass().withRedefinedSuperclass().verify();
  	}
  
  	public class AddHash extends ClassTypeTest {
  
  		@Test
  		public void addHashToNotInitialized() {
  			String fqn1 = "fqn1";
  			String hash = "hash";
  			test = new ClassType(fqn1);
  
  			test.addHash(hash);
  
  			assertThat(test.getHashes(), contains(hash));
  			assertThat(test.getHashes().size(), is(1));
  		}
  
  		@Test
  		public void addHashToInitialized() {
  			String fqn1 = "fqn1";
  			String storedHash = "shash";
  			String hash = "hash";
  			test = new ClassType(fqn1, storedHash, 0);
  
  			test.addHash(hash);
  
  			assertThat(test.getHashes().size(), is(2));
  			assertThat(test.getHashes(), hasItem(storedHash));
  			assertThat(test.getHashes(), hasItem(hash));
  		}
  	}
  
  	public class SetModifiers extends ClassTypeTest {
  
  		@Test
  		public void setModifier() {
  			String fqn1 = "fqn1";
  			String storedHash = "shash";
  			int m = 0;
  			test = new ClassType(fqn1, storedHash, m);
  			int m2 = 2;
  
  			test.setModifiers(m2);
  
  			assertThat(test.getModifiers(), is(equalTo(m2)));
  		}
  	}
  
  	public class AddSuperClass extends ClassTypeTest {
  
  		@Test
  		public void addSuperClass() {
  			String fqn1 = "fqn1";
  			String fqn2 = "fqn2";
  			test = new ClassType(fqn1);
  			ClassType superclass = new ClassType(fqn2);
  
  			test.addSuperClass(superclass);
  
  			assertThat(test.getSuperClasses(), hasItem(superclass));
  			assertThat(superclass.getSubClasses(), hasItem(test));
  		}
  	}
  
  	public class AddSubClass extends ClassTypeTest {
  
  		@Test
  		public void addSubClass() {
  			String fqn1 = "fqn1";
  			String fqn2 = "fqn2";
  			test = new ClassType(fqn1);
  			ClassType subclass = new ClassType(fqn2);
  
  			test.addSubclass(subclass);
  
  			assertThat(test.getSubClasses(), hasItem(subclass));
  			assertThat(subclass.getSuperClasses(), hasItem(test));
  		}
  	}
  
  	public class AddInterface extends ClassTypeTest {
  
  		@Test
  		public void addRealizingInterface() {
  			String fqn1 = "fqn1";
  			String fqn2 = "fqn2";
  			test = new ClassType(fqn1);
  			InterfaceType i = new InterfaceType(fqn2);
  
  			test.addInterface(i);
  
  			assertThat(test.getRealizedInterfaces(), hasItem(i));
  			assertThat(i.getRealizingClasses(), hasItem(test));
  		}
  	}
  
  	public class AddMethod extends ClassTypeTest {
  
  		@Test
  		public void addMethod() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			MethodType m = new MethodType();
  
  			test.addMethod(m);
  
  			assertThat(test.getMethods(), hasItem(m));
  			assertThat(m.getClassOrInterfaceType(), is(equalTo((TypeWithMethods) test)));
  		}
  	}
  
  	public class AddAnnotation extends ClassTypeTest {
  
  		@Test
  		public void addAnnotation() {
  			String fqn1 = "fqn1";
  			String fqn2 = "fqn2";
  			test = new ClassType(fqn1);
  			AnnotationType a = new AnnotationType(fqn2);
  
  			test.addAnnotation(a);
  
  			assertThat(test.getAnnotations(), hasItem(a));
  			assertThat(a.getAnnotatedTypes(), hasItem((TypeWithAnnotations) test));
  		}
  	}
  
  	public class AddMethodThrowingException extends ClassTypeTest {
  
  		@Test
  		public void addMethodThrowsException() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			MethodType m = new MethodType();
  
  			test.addMethodThrowingException(m);
  
  			assertThat(test.getMethodsThrowingThisException(), hasItem(m));
  			assertThat(m.getExceptions(), hasItem(test));
  		}
  	}
  
  	public class HasInstrumentationPoints extends ClassTypeTest {
  
  		@Test
  		public void noInstrumentationPointsNoMethods() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  
  			boolean hasInstrumentationPoints = test.hasInstrumentationPoints();
  
  			assertThat(hasInstrumentationPoints, is(false));
  		}
  
  		@Test
  		public void noInstrumentationMethodDoesNotHave() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			MethodType m = new MethodType();
  			test.addMethod(m);
  
  			boolean hasInstrumentationPoints = test.hasInstrumentationPoints();
  
  			assertThat(hasInstrumentationPoints, is(false));
  		}
  
  		@Test
  		public void hasInstrumentationPoints() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			MethodInstrumentationConfig config = new MethodInstrumentationConfig();
  			MethodType m = new MethodType();
  			m.setMethodInstrumentationConfig(config);
  			test.addMethod(m);
  
  			boolean hasInstrumentationPoints = test.hasInstrumentationPoints();
  
  			assertThat(hasInstrumentationPoints, is(true));
  		}
  	}
  
  	public class GetInstrumentationPoints extends ClassTypeTest {
  
  		@Test
  		public void noInstrumentationPointsNoMethods() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  
  			Collection<MethodInstrumentationConfig> instrumentationPoints = test.getInstrumentationPoints();
  
  			assertThat(instrumentationPoints, is(empty()));
  		}
  
  		@Test
  		public void noInstrumentationMethodDoesNotHave() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			MethodType m = new MethodType();
  			test.addMethod(m);
  
  			Collection<MethodInstrumentationConfig> instrumentationPoints = test.getInstrumentationPoints();
  
  			assertThat(instrumentationPoints, is(empty()));
  		}
  
  		@Test
  		public void hasInstrumentationPoints() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			MethodInstrumentationConfig config = new MethodInstrumentationConfig();
  			MethodType m = new MethodType();
  			m.setMethodInstrumentationConfig(config);
  			test.addMethod(m);
  
  			Collection<MethodInstrumentationConfig> instrumentationPoints = test.getInstrumentationPoints();
  
  			assertThat(instrumentationPoints, hasSize(1));
  			assertThat(instrumentationPoints, hasItem(config));
  		}
  	}
  
  	public class IsException extends ClassTypeTest {
  
  		@Test
  		public void doesNotHaveSuperClass() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  
  			boolean exception = test.isException();
  
  			assertThat(exception, is(false));
  		}
  
  		@Test
  		public void superClassIsNotException() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			ClassType superClass = new ClassType("some.Class");
  			test.addSuperClass(superClass);
  
  			boolean exception = test.isException();
  
  			assertThat(exception, is(false));
  		}
  
  		@Test
  		public void superClassIsException() {
  			String fqn1 = "fqn1";
  			test = new ClassType(fqn1);
  			ClassType superClass = new ClassType("java.lang.Throwable");
  			test.addSuperClass(superClass);
  
  			boolean exception = test.isException();
  
  			assertThat(exception, is(true));
  		}
  	}
  
  }
  