/* * Copyright 2016 Lukas Krejci * * 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.revapi.java; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Stream; import javax.annotation.Nullable; import org.junit.Assert; import org.junit.Test; import org.revapi.API; import org.revapi.AnalysisContext; import org.revapi.ArchiveAnalyzer; import org.revapi.Element; import org.revapi.ElementForest; import org.revapi.simple.SimpleElementFilter; /** * @author Lukas Krejci * @since 0.7.0 */ public class ClassFilterTest extends AbstractJavaElementAnalyzerTest { @Test public void testSimpleFilterByName_exclude() throws Exception { testWith("{\"revapi\": {\"java\": {\"filter\": {\"classes\": {\"exclude\": [\"classfilter.A\"]}}}}}", Stream.of( "class classfilter.B", "field classfilter.B.field", "method void classfilter.B::m()", "method void classfilter.B::<init>()", "class classfilter.B.BA", "method void classfilter.B.BA::<init>()", "class classfilter.B.BB", "method void classfilter.B.BB::<init>()").collect(toSet())); } @Test public void testSimpleFilterByName_include() throws Exception { testWith("{\"revapi\": {\"java\": {\"filter\": {\"classes\": {\"include\": [\"classfilter.A\"]}}}}}", Stream.of( "class classfilter.A", "method void classfilter.A::m()", "method void classfilter.A::<init>()", "class classfilter.A.AA", "method void classfilter.A.AA::<init>()", "class classfilter.A.AA.AAA", "method void classfilter.A.AA.AAA::<init>()", "class classfilter.A.AB", "method void classfilter.A.AB::<init>()").collect(toSet())); } @Test public void testInnerClassExclusionOverride() throws Exception { testWith("{\"revapi\": {\"java\": {\"filter\": {\"classes\": {\"exclude\": [\"classfilter.A\"]," + " \"include\": [\"classfilter.A.AA.AAA\", \"classfilter.B\"]}}}}}", Stream.of( "class classfilter.A.AA.AAA", "method void classfilter.A.AA.AAA::<init>()", "class classfilter.B", "field classfilter.B.field", "method void classfilter.B::m()", "method void classfilter.B::<init>()", "class classfilter.B.BA", "method void classfilter.B.BA::<init>()", "class classfilter.B.BB", "method void classfilter.B.BB::<init>()").collect(toSet())); } @Test public void testRegexFilter() throws Exception { testWith("{\"revapi\": {\"java\": {\"filter\": {\"classes\": {\"regex\": true," + " \"exclude\": [\"classfilter\\.(A|B\\.BB)\"]}}}}}", Stream.of( "class classfilter.B", "field classfilter.B.field", "method void classfilter.B::m()", "method void classfilter.B::<init>()", "class classfilter.B.BA", "method void classfilter.B.BA::<init>()").collect(toSet())); } private void testWith(String configJSON, Set<String> expectedResults) throws Exception { ArchiveAndCompilationPath archive = createCompiledJar("test.jar", "classfilter/A.java", "classfilter/B.java"); testWith(archive, configJSON, expectedResults); } static void testWith(ArchiveAndCompilationPath archive, String configJSON, Set<String> expectedResults) throws Exception { try { JavaApiAnalyzer apiAnalyzer = new JavaApiAnalyzer(Collections.emptyList()); AnalysisContext ctx = AnalysisContext.builder().withConfigurationFromJSON(configJSON).build(); apiAnalyzer.initialize(ctx); ArchiveAnalyzer archiveAnalyzer = apiAnalyzer.getArchiveAnalyzer( new API(Collections.singletonList(new ShrinkwrapArchive(archive.archive)), null)); ElementForest forest = archiveAnalyzer.analyze(); List<Element> results = forest.search(Element.class, true, new AcceptingFilter(), null); List<String> expected = new ArrayList<>(expectedResults); List<String> actual = results.stream() //don't include stuff from the system classpath, because that makes the results unnecessarily //huge, while we don't actually need to check the system classpath element at all in the tests .filter(e -> e.getArchive() != null && !e.getArchive().getName().equals("<system classpath>")) .map(Element::getFullHumanReadableString).collect(toList()); Collections.sort(expected); Collections.sort(actual); Assert.assertEquals(expected, actual); } finally { deleteDir(archive.compilationPath); } } private static class AcceptingFilter extends SimpleElementFilter { @Override public boolean applies(@Nullable Element element) { return true; } @Override public boolean shouldDescendInto(@Nullable Object element) { return true; } } }