/* * Copyright 2010 Henry Coles * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License. */ package org.pitest.classinfo; import static java.lang.annotation.ElementType.TYPE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.Test; import org.junit.experimental.categories.Category; import org.pitest.coverage.codeassist.ClassUtils; import org.pitest.coverage.codeassist.samples.Bridge.HasBridgeMethod; import org.pitest.coverage.codeassist.samples.HasDefaultConstructor; import org.pitest.coverage.codeassist.samples.NoDefaultConstructor; public class ClassInfoVisitorTest { @Test public void shouldDetectStandardCodeLines() throws Exception { final String sampleName = NoDefaultConstructor.class.getName(); final ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertTrue(actual.codeLines.contains(25)); } @Test public void shouldDetectCodeLineAtClassDeclarationsWhenClassHasDefaultConstructor() throws Exception { final String sampleName = HasDefaultConstructor.class.getName(); final ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertTrue( "first line of class with default constructor should be a code line", actual.codeLines.contains(17)); assertFalse("line before should not be a code line", actual.codeLines.contains(16)); } @Test public void shouldNotDetectCodeLineAtClassDeclarationsWhenClassHasNoDefaultConstructor() throws Exception { final String sampleName = NoDefaultConstructor.class.getName(); final ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertFalse( "first line of class without default constructor should not be a code line", actual.codeLines.contains(17)); } @Test public void shouldNotRecordLineNumbersFromSyntheticBridgeMethods() throws Exception { final String sampleName = HasBridgeMethod.class.getName(); final ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertFalse(actual.codeLines.contains(1)); } @Test public void shouldRecordSourceFile() throws ClassNotFoundException { final String sampleName = String.class.getName(); final ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertEquals("String.java", actual.sourceFile); } @Test public void shouldRecordClassAnnotationValues() throws ClassNotFoundException { final String sampleName = HasSimpleValue.class.getName(); ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertEquals(1, actual.classAnnotationValues.size()); Object expectedValue = "blah"; Object actualValue = actual.classAnnotationValues.get(ClassName .fromClass(SimpleValue.class)); assertEquals(expectedValue, actualValue); } @Test public void shouldRecordClassAnnotationArrayValues() throws ClassNotFoundException { final String sampleName = HasStringValues.class.getName(); ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertEquals(1, actual.classAnnotationValues.size()); Object[] expectedStrings = { "this", "that" }; Object[] actualStrings = (Object[]) actual.classAnnotationValues .get(ClassName.fromClass(StringValues.class)); assertArrayEquals(expectedStrings, actualStrings); } @Test public void shouldStoreTypeArrayValuesAsClassNames() throws ClassNotFoundException { final String sampleName = HasCategory.class.getName(); ClassInfoBuilder actual = getClassInfo(sampleName, ClassUtils.classAsBytes(sampleName)); assertEquals(1, actual.classAnnotationValues.size()); Object[] expectedCategoryNames = { First.class.getName(), Second.class.getName() }; Object[] actualCategoryNames = (Object[]) actual.classAnnotationValues .get(ClassName.fromClass(Category.class)); assertArrayEquals(expectedCategoryNames, actualCategoryNames); } private ClassInfoBuilder getClassInfo(final String name, final byte[] bytes) { return ClassInfoVisitor.getClassInfo(new ClassName(name), bytes, 0); } @Target(TYPE) @Retention(RetentionPolicy.RUNTIME) private @interface SimpleValue { String value(); } @SimpleValue("blah") private class HasSimpleValue { } @Target(TYPE) @Retention(RetentionPolicy.RUNTIME) private @interface StringValues { String[] value(); } @StringValues({ "this", "that" }) private class HasStringValues { } private interface First { } private interface Second { } @Category({ First.class, Second.class }) private class HasCategory { } }