package com.sebastian_daschner.jaxrs_analyzer.analysis.bytecode;
import com.sebastian_daschner.jaxrs_analyzer.analysis.JobRegistry;
import com.sebastian_daschner.jaxrs_analyzer.analysis.classes.ContextClassReader;
import com.sebastian_daschner.jaxrs_analyzer.analysis.classes.ProjectMethodClassVisitor;
import com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils;
import com.sebastian_daschner.jaxrs_analyzer.model.methods.MethodIdentifier;
import com.sebastian_daschner.jaxrs_analyzer.model.results.ClassResult;
import com.sebastian_daschner.jaxrs_analyzer.model.results.MethodResult;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.ArgumentCaptor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
import javax.ws.rs.NotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Set;
import java.util.stream.Collectors;
import static com.sebastian_daschner.jaxrs_analyzer.analysis.utils.TestClassUtils.getClasses;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
@RunWith(Parameterized.class)
public class SubResourceLocatorMethodContentAnalyzerTest {
private static JobRegistry originalJobRegistry;
private final SubResourceLocatorMethodContentAnalyzer classUnderTest;
private final String testClassSimpleName;
private final String testClassName;
private final Set<String> expectedClassNames;
private final JobRegistry jobRegistry;
private String signature;
public SubResourceLocatorMethodContentAnalyzerTest(final String testClassSimpleName, final String testClassName, final String signature, final Set<String> expectedClassNames)
throws ReflectiveOperationException {
this.testClassSimpleName = testClassSimpleName;
this.testClassName = testClassName;
this.signature = signature;
this.expectedClassNames = expectedClassNames;
jobRegistry = mock(JobRegistry.class);
this.classUnderTest = new SubResourceLocatorMethodContentAnalyzer();
injectJobRegistry(jobRegistry);
}
@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> data() throws NotFoundException, IOException, ReflectiveOperationException {
Collection<Object[]> data = new LinkedList<>();
final Set<String> testClasses = getClasses("com/sebastian_daschner/jaxrs_analyzer/analysis/bytecode/subresource");
for (final String testClass : testClasses) {
final Object[] testData = new Object[4];
final Class<?> loadedClass = JavaUtils.loadClassFromName(testClass);
testData[0] = testClass.substring(testClass.lastIndexOf('/') + 1);
testData[1] = testClass;
testData[2] = Type.getMethodDescriptor(loadedClass.getDeclaredMethod("method"));
testData[3] = loadedClass.getDeclaredMethod("getResult").invoke(null);
data.add(testData);
}
return data;
}
@Test
public void test() throws IOException {
try {
final ClassReader classReader = new ContextClassReader(testClassName);
final MethodResult methodResult = new MethodResult();
final ClassResult parentResource = new ClassResult();
parentResource.setOriginalClass(testClassName);
methodResult.setParentResource(parentResource);
final ProjectMethodClassVisitor visitor = new ProjectMethodClassVisitor(methodResult, MethodIdentifier.of(testClassName, "method", signature, false));
classReader.accept(visitor, ClassReader.EXPAND_FRAMES);
classUnderTest.analyze(methodResult);
} catch (Exception e) {
System.err.println("failed for " + testClassName);
throw e;
}
final ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(jobRegistry, atLeastOnce()).analyzeResourceClass(captor.capture(), any());
assertEquals("failed for " + testClassName, expectedClassNames, captor.getAllValues().stream().collect(Collectors.toSet()));
verify(jobRegistry, times(expectedClassNames.size())).analyzeResourceClass(any(), any());
}
@AfterClass
public static void tearDown() throws NoSuchFieldException, IllegalAccessException {
injectJobRegistry(originalJobRegistry);
}
private static void injectJobRegistry(final JobRegistry jobRegistry) throws NoSuchFieldException, IllegalAccessException {
final Field field = JobRegistry.class.getDeclaredField("INSTANCE");
field.setAccessible(true);
originalJobRegistry = JobRegistry.getInstance();
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, jobRegistry);
}
}