use of org.revapi.API in project revapi by revapi.
the class JavaArchiveAnalyzerTest method testTypeParametersDragIntoAPI.
@Test
public void testTypeParametersDragIntoAPI() throws Exception {
ArchiveAndCompilationPath compRes = createCompiledJar("a.jar", "misc/Generics.java", "misc/GenericsParams.java");
JavaArchive api = ShrinkWrap.create(JavaArchive.class, "api.jar").addAsResource(compRes.compilationPath.resolve("Generics.class").toFile(), "Generics.class");
JavaArchive sup = ShrinkWrap.create(JavaArchive.class, "sup.jar").addAsResource(compRes.compilationPath.resolve("GenericsParams.class").toFile(), "GenericsParams.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeParam.class").toFile(), "GenericsParams$TypeParam.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$ExtendsBound.class").toFile(), "GenericsParams$ExtendsBound.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$SuperBound.class").toFile(), "GenericsParams$SuperBound.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVar.class").toFile(), "GenericsParams$TypeVar.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVarIface.class").toFile(), "GenericsParams$TypeVarIface.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVarImpl.class").toFile(), "GenericsParams$TypeVarImpl.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$Unused.class").toFile(), "GenericsParams$Unused.class");
JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(api)), Arrays.asList(new ShrinkwrapArchive(sup))), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
try {
JavaElementForest forest = analyzer.analyze();
Set<TypeElement> roots = forest.getRoots();
Assert.assertEquals(7, roots.size());
Assert.assertTrue(roots.stream().anyMatch(hasName("class Generics<T extends GenericsParams.TypeVar, GenericsParams.TypeVarIface, U extends Generics<GenericsParams.TypeVarImpl, ?>>")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.ExtendsBound")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.SuperBound")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeParam")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeVar")));
Assert.assertTrue(roots.stream().anyMatch(hasName("interface GenericsParams.TypeVarIface")));
Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeVarImpl")));
Assert.assertFalse(roots.stream().anyMatch(hasName("class GenericsParams.Unused")));
} finally {
deleteDir(compRes.compilationPath);
analyzer.getCompilationValve().removeCompiledResults();
}
}
use of org.revapi.API in project revapi by revapi.
the class JavaArchiveAnalyzerTest method testPreventRecursionWhenConstructingInheritedMembers.
@Test
public void testPreventRecursionWhenConstructingInheritedMembers() throws Exception {
ArchiveAndCompilationPath archive = createCompiledJar("a.jar", "misc/MemberInheritsOwner.java");
JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(archive.archive)), null), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
try {
JavaElementForest forest = analyzer.analyze();
forest.getRoots();
Assert.assertEquals(1, forest.getRoots().size());
Predicate<Element> findMethod = c -> "method void MemberInheritsOwner::method()".equals(c.getFullHumanReadableString());
Predicate<Element> findMember1 = c -> "interface MemberInheritsOwner.Member1".equals(c.getFullHumanReadableString());
Predicate<Element> findMember2 = c -> "interface MemberInheritsOwner.Member2".equals(c.getFullHumanReadableString());
Element root = forest.getRoots().first();
Assert.assertEquals(3, root.getChildren().size());
Assert.assertTrue(root.getChildren().stream().anyMatch(findMethod));
Assert.assertTrue(root.getChildren().stream().anyMatch(findMember1));
Assert.assertTrue(root.getChildren().stream().anyMatch(findMember2));
Assert.assertEquals(1, root.getChildren().stream().filter(findMember1).findFirst().get().getChildren().size());
Assert.assertEquals(1, root.getChildren().stream().filter(findMember2).findFirst().get().getChildren().size());
} finally {
deleteDir(archive.compilationPath);
analyzer.getCompilationValve().removeCompiledResults();
}
}
use of org.revapi.API in project revapi by revapi.
the class BuildTimeReporterTest method testJSONEscapedInIgnoreHint.
@Test
public void testJSONEscapedInIgnoreHint() {
BuildTimeReporter reporter = new BuildTimeReporter();
API oldApi = API.builder().build();
API newApi = API.builder().build();
AnalysisContext ctx = AnalysisContext.builder().withOldAPI(oldApi).withNewAPI(newApi).withData(BuildTimeReporter.BREAKING_SEVERITY_KEY, DifferenceSeverity.EQUIVALENT).build();
reporter.initialize(ctx);
Element oldEl = new SimpleElement() {
@Nonnull
@Override
public API getApi() {
return oldApi;
}
@Nullable
@Override
public Archive getArchive() {
return null;
}
@Override
public int compareTo(Element o) {
return 0;
}
@Override
public String toString() {
return "old element";
}
};
Element newEl = new SimpleElement() {
@Nonnull
@Override
public API getApi() {
return newApi;
}
@Nullable
@Override
public Archive getArchive() {
return null;
}
@Override
public int compareTo(Element o) {
return 0;
}
@Override
public String toString() {
return "new element";
}
};
Report report = Report.builder().withNew(newEl).withOld(oldEl).addProblem().withCode("diffs\\myDiff").withDescription("the problem").addClassification(CompatibilityType.BINARY, DifferenceSeverity.BREAKING).addAttachment("shouldBeEscaped", "{\"a\", \"b\"}").done().build();
reporter.report(report);
String resultMessage = reporter.getAllProblemsMessage();
Assert.assertNotNull(resultMessage);
int start = resultMessage.indexOf('{');
int end = resultMessage.lastIndexOf('}');
String json = resultMessage.substring(start, end + 1);
json = json.replace("<<<<< ADD YOUR EXPLANATION FOR THE NECESSITY OF THIS CHANGE >>>>>", "\"\"");
ModelNode parsed = ModelNode.fromJSONString(json);
Assert.assertEquals("diffs\\myDiff", parsed.get("code").asString());
Assert.assertEquals("{\"a\", \"b\"}", parsed.get("shouldBeEscaped").asString());
}
use of org.revapi.API in project revapi by revapi.
the class Analyzer method resolveArtifacts.
@SuppressWarnings("unchecked")
void resolveArtifacts() {
if (resolvedOldApi == null) {
final ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, project.getRemoteProjectRepositories());
Function<String, MavenArchive> toFileArchive = gav -> {
try {
Artifact a = resolveConstrained(project, gav, versionRegex, resolver);
return MavenArchive.of(a);
} catch (ArtifactResolutionException | VersionRangeResolutionException | IllegalArgumentException e) {
throw new MarkerException(e.getMessage(), e);
}
};
List<MavenArchive> oldArchives = new ArrayList<>(1);
try {
if (oldGavs != null) {
oldArchives = Stream.of(oldGavs).map(toFileArchive).collect(toList());
}
if (oldArtifacts != null) {
oldArchives.addAll(Stream.of(oldArtifacts).map(MavenArchive::of).collect(toList()));
}
} catch (MarkerException | IllegalArgumentException e) {
String message = "Failed to resolve old artifacts: " + e.getMessage() + ".";
if (failOnMissingArchives) {
throw new IllegalStateException(message, e);
} else {
log.warn(message + " The API analysis will proceed comparing the new archives against an empty" + " archive.");
}
}
List<MavenArchive> newArchives = new ArrayList<>(1);
try {
if (newGavs != null) {
newArchives = Stream.of(newGavs).map(toFileArchive).collect(toList());
}
if (newArtifacts != null) {
newArchives.addAll(Stream.of(newArtifacts).map(MavenArchive::of).collect(toList()));
}
} catch (MarkerException | IllegalArgumentException e) {
String message = "Failed to resolve new artifacts: " + e.getMessage() + ".";
if (failOnMissingArchives) {
throw new IllegalStateException(message, e);
} else {
log.warn(message + " The API analysis will not proceed.");
return;
}
}
// now we need to be a little bit clever. When using RELEASE or LATEST as the version of the old artifact
// it might happen that it gets resolved to the same version as the new artifacts - this notoriously happens
// when releasing using the release plugin - you first build your artifacts, put them into the local repo
// and then do the site updates for the released version. When you do the site, maven will find the released
// version in the repo and resolve RELEASE to it. You compare it against what you just built, i.e. the same
// code, et voila, the site report doesn't ever contain any found differences...
Set<MavenArchive> oldTransitiveDeps = new HashSet<>();
Set<MavenArchive> newTransitiveDeps = new HashSet<>();
if (resolveDependencies) {
String[] resolvedOld = oldArchives.stream().map(MavenArchive::getName).toArray(String[]::new);
String[] resolvedNew = newArchives.stream().map(MavenArchive::getName).toArray(String[]::new);
oldTransitiveDeps.addAll(collectDeps("old", resolver, resolvedOld));
newTransitiveDeps.addAll(collectDeps("new", resolver, resolvedNew));
}
resolvedOldApi = API.of(oldArchives).supportedBy(oldTransitiveDeps).build();
resolvedNewApi = API.of(newArchives).supportedBy(newTransitiveDeps).build();
}
}
use of org.revapi.API in project revapi by revapi.
the class JavaArchiveAnalyzerTest method testWithSupplementary.
@Test
public void testWithSupplementary() throws Exception {
ArchiveAndCompilationPath compRes = createCompiledJar("a.jar", "v1/supplementary/a/A.java", "v1/supplementary/b/B.java", "v1/supplementary/a/C.java");
JavaArchive api = ShrinkWrap.create(JavaArchive.class, "api.jar").addAsResource(compRes.compilationPath.resolve("A.class").toFile(), "A.class");
JavaArchive sup = ShrinkWrap.create(JavaArchive.class, "sup.jar").addAsResource(compRes.compilationPath.resolve("B.class").toFile(), "B.class").addAsResource(compRes.compilationPath.resolve("B$T$1.class").toFile(), "B$T$1.class").addAsResource(compRes.compilationPath.resolve("B$T$1$TT$1.class").toFile(), "B$T$1$TT$1.class").addAsResource(compRes.compilationPath.resolve("B$T$2.class").toFile(), "B$T$2.class").addAsResource(compRes.compilationPath.resolve("C.class").toFile(), "C.class").addAsResource(compRes.compilationPath.resolve("B$UsedByIgnoredClass.class").toFile(), "B$UsedByIgnoredClass.class").addAsResource(compRes.compilationPath.resolve("A$PrivateEnum.class").toFile(), "A$PrivateEnum.class");
JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(api)), Arrays.asList(new ShrinkwrapArchive(sup))), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
try {
JavaElementForest forest = analyzer.analyze();
Assert.assertEquals(3, forest.getRoots().size());
Iterator<TypeElement> roots = forest.getRoots().iterator();
TypeElement A = roots.next();
TypeElement B_T$1 = roots.next();
TypeElement B_T$2 = roots.next();
Assert.assertEquals("A", A.getCanonicalName());
Assert.assertEquals("A", A.getDeclaringElement().getQualifiedName().toString());
Assert.assertEquals("B.T$1", B_T$1.getCanonicalName());
Assert.assertEquals("B.T$1", B_T$1.getDeclaringElement().getQualifiedName().toString());
Assert.assertEquals("B.T$2", B_T$2.getCanonicalName());
Assert.assertEquals("B.T$2", B_T$2.getDeclaringElement().getQualifiedName().toString());
} finally {
deleteDir(compRes.compilationPath);
analyzer.getCompilationValve().removeCompiledResults();
}
}
Aggregations