From 4542f3be3926aff9a59fd8a778b4f4db71eef853 Mon Sep 17 00:00:00 2001 From: Tanish Ranjan <62828604+Tanish-Ranjan@users.noreply.github.com> Date: Wed, 4 Sep 2024 04:01:46 +0530 Subject: [PATCH] Added test variants to the source sets. Changes: - Added android resource directories only if the variant is not a unit test - Updated GradleApiConnectorTest#testAndroidSourceSets to consider the all the test variants and their dependencies - Addressed checkstyle issues --- .../bs/gradle/plugin/utils/AndroidUtils.java | 148 +++++++++++++----- .../gradle/GradleApiConnectorTest.java | 17 +- 2 files changed, 115 insertions(+), 50 deletions(-) diff --git a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/utils/AndroidUtils.java b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/utils/AndroidUtils.java index 9f2f6954..689c1b15 100644 --- a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/utils/AndroidUtils.java +++ b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/utils/AndroidUtils.java @@ -96,7 +96,8 @@ public static List getBuildVariantsAsGradleSourceSets(Project p try { Set variants = (Set) invokeMethod(androidExtension, methodName); for (Object variant : variants) { - GradleSourceSet sourceSet = convertVariantToGradleSourceSet(project, variant); + GradleSourceSet sourceSet = + convertVariantToGradleSourceSet(project, variant, sourceSets, false); if (sourceSet == null) { continue; } @@ -116,8 +117,15 @@ public static List getBuildVariantsAsGradleSourceSets(Project p * * @param project Gradle project to populate GradleSourceSet properties * @param variant Android Build Variant object to populate GradleSourceSet properties + * @param sourceSets List of source sets to which test variants will be added + * @param isUnitTest Indicates if the given variant is a unit test variant */ - private static GradleSourceSet convertVariantToGradleSourceSet(Project project, Object variant) { + private static GradleSourceSet convertVariantToGradleSourceSet( + Project project, + Object variant, + List sourceSets, + boolean isUnitTest + ) { try { @@ -154,16 +162,16 @@ private static GradleSourceSet convertVariantToGradleSourceSet(Project project, String displayName = projectName + " [" + variantName + ']'; gradleSourceSet.setDisplayName(displayName); - List compilerArgs = new ArrayList<>(); - // module dependencies addModuleDependencies(gradleSourceSet, project, variant); // source and resource - addSourceAndResources(gradleSourceSet, variant); + addSourceAndResources(gradleSourceSet, variant, isUnitTest); // resource outputs - addResourceOutputs(gradleSourceSet, variant); + addResourceOutputs(gradleSourceSet, variant, isUnitTest); + + List compilerArgs = new ArrayList<>(); // generated sources and source outputs addGeneratedSourceAndSourceOutputs(gradleSourceSet, variant, compilerArgs); @@ -175,7 +183,7 @@ private static GradleSourceSet convertVariantToGradleSourceSet(Project project, gradleSourceSet.setArchiveOutputFiles(new HashMap<>()); // has tests - addTests(gradleSourceSet, variant); + addTests(gradleSourceSet, project, variant, sourceSets); // extensions addExtensions(gradleSourceSet, compilerArgs); @@ -196,11 +204,16 @@ private static GradleSourceSet convertVariantToGradleSourceSet(Project project, * @param variant Instance of Build Variant */ @SuppressWarnings("unchecked") - private static void addModuleDependencies(DefaultGradleSourceSet gradleSourceSet, Project project, Object variant) { + private static void addModuleDependencies( + DefaultGradleSourceSet gradleSourceSet, + Project project, + Object variant + ) { + + Set moduleDependencies = + AndroidDependencyCollector.getModuleDependencies(project, variant); try { - Set moduleDependencies = - AndroidDependencyCollector.getModuleDependencies(project, variant); // add Android SDK Object androidComponents = getAndroidComponentExtension(project); if (androidComponents != null) { @@ -231,11 +244,12 @@ private static void addModuleDependencies(DefaultGradleSourceSet gradleSourceSet moduleDependencies.add(mockModuleDependency(jarFile.toURI())); } } - gradleSourceSet.setModuleDependencies(moduleDependencies); } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { // do nothing } + gradleSourceSet.setModuleDependencies(moduleDependencies); + } /** @@ -243,33 +257,38 @@ private static void addModuleDependencies(DefaultGradleSourceSet gradleSourceSet * * @param gradleSourceSet Instance of DefaultGradleSourceSet * @param variant Instance of Build Variant + * @param isUnitTest Indicates if the given variant is a unit test variant */ @SuppressWarnings("unchecked") - private static void addSourceAndResources(DefaultGradleSourceSet gradleSourceSet, Object variant) { + private static void addSourceAndResources( + DefaultGradleSourceSet gradleSourceSet, + Object variant, + boolean isUnitTest + ) { + + Set sourceDirs = new HashSet<>(); + Set resourceDirs = new HashSet<>(); try { Object sourceSets = getProperty(variant, "sourceSets"); - Set sourceDirs = new HashSet<>(); - Set resourceDirs = new HashSet<>(); if (sourceSets instanceof Iterable) { for (Object sourceSet : (Iterable) sourceSets) { Set javaDirectories = (Set) getProperty(sourceSet, "javaDirectories"); - Set resDirectories = - (Set) getProperty(sourceSet, "resDirectories"); - Set resourceDirectories = - (Set) getProperty(sourceSet, "resourcesDirectories"); sourceDirs.addAll(javaDirectories); - resourceDirs.addAll(resDirectories); - resourceDirs.addAll(resourceDirectories); + if (!isUnitTest) { + resourceDirs.addAll((Set) getProperty(sourceSet, "resDirectories")); + } + resourceDirs.addAll((Set) getProperty(sourceSet, "resourcesDirectories")); } } - gradleSourceSet.setSourceDirs(sourceDirs); - gradleSourceSet.setResourceDirs(resourceDirs); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { // do nothing } + gradleSourceSet.setSourceDirs(sourceDirs); + gradleSourceSet.setResourceDirs(resourceDirs); + } /** @@ -277,12 +296,18 @@ private static void addSourceAndResources(DefaultGradleSourceSet gradleSourceSet * * @param gradleSourceSet Instance of DefaultGradleSourceSet * @param variant Instance of Build Variant + * @param isUnitTest Indicates if the given variant is a unit test variant */ @SuppressWarnings("unchecked") - private static void addResourceOutputs(DefaultGradleSourceSet gradleSourceSet, Object variant) { + private static void addResourceOutputs( + DefaultGradleSourceSet gradleSourceSet, + Object variant, + boolean isUnitTest + ) { + + Set resourceOutputs = new HashSet<>(); try { - Set resourceOutputs = new HashSet<>(); Provider resourceProvider = (Provider) getProperty(variant, "processJavaResourcesProvider"); if (resourceProvider != null) { @@ -290,19 +315,23 @@ private static void addResourceOutputs(DefaultGradleSourceSet gradleSourceSet, O File outputDir = (File) invokeMethod(resTask, "getDestinationDir"); resourceOutputs.add(outputDir); } - Provider resProvider = - (Provider) getProperty(variant, "mergeResourcesProvider"); - if (resProvider != null) { - Task resTask = resProvider.get(); - Object outputDir = invokeMethod(resTask, "getOutputDir"); - File output = ((Provider) invokeMethod(outputDir, "getAsFile")).get(); - resourceOutputs.add(output); + + if (!isUnitTest) { + Provider resProvider = + (Provider) getProperty(variant, "mergeResourcesProvider"); + if (resProvider != null) { + Task resTask = resProvider.get(); + Object outputDir = invokeMethod(resTask, "getOutputDir"); + File output = ((Provider) invokeMethod(outputDir, "getAsFile")).get(); + resourceOutputs.add(output); + } } - gradleSourceSet.setResourceOutputDirs(resourceOutputs); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { // do nothing } + gradleSourceSet.setResourceOutputDirs(resourceOutputs); + } /** @@ -313,11 +342,16 @@ private static void addResourceOutputs(DefaultGradleSourceSet gradleSourceSet, O * @param compilerArgs List to be populated from the java compiler arguments. */ @SuppressWarnings("unchecked") - private static void addGeneratedSourceAndSourceOutputs(DefaultGradleSourceSet gradleSourceSet, Object variant, List compilerArgs) { + private static void addGeneratedSourceAndSourceOutputs( + DefaultGradleSourceSet gradleSourceSet, + Object variant, + List compilerArgs + ) { + + Set generatedSources = new HashSet<>(); + Set sourceOutputs = new HashSet<>(); try { - Set generatedSources = new HashSet<>(); - Set sourceOutputs = new HashSet<>(); Provider javaCompileProvider = (Provider) getProperty(variant, "javaCompileProvider"); if (javaCompileProvider != null) { @@ -346,12 +380,13 @@ private static void addGeneratedSourceAndSourceOutputs(DefaultGradleSourceSet gr generatedSources.add(compileSource); } } - gradleSourceSet.setGeneratedSourceDirs(generatedSources); - gradleSourceSet.setSourceOutputDirs(sourceOutputs); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { // do nothing } + gradleSourceSet.setGeneratedSourceDirs(generatedSources); + gradleSourceSet.setSourceOutputDirs(sourceOutputs); + } /** @@ -362,26 +397,54 @@ private static void addGeneratedSourceAndSourceOutputs(DefaultGradleSourceSet gr */ @SuppressWarnings("unchecked") private static void addClasspath(DefaultGradleSourceSet gradleSourceSet, Object variant) { + + Set classpathFiles = new HashSet<>(); + try { Object compileConfig = invokeMethod(variant, "getCompileConfiguration"); - Set classpathFiles = (Set) invokeMethod(compileConfig, "getFiles"); - gradleSourceSet.setCompileClasspath(new LinkedList<>(classpathFiles)); + classpathFiles.addAll((Set) invokeMethod(compileConfig, "getFiles")); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { // do nothing } + + gradleSourceSet.setCompileClasspath(new LinkedList<>(classpathFiles)); + } /** * Add classpath files to the given GradleSourceSet. * * @param gradleSourceSet Instance of DefaultGradleSourceSet + * @param project Instance of Project * @param variant Instance of Build Variant + * @param sourceSets List of source sets to which test variants will be added */ - private static void addTests(DefaultGradleSourceSet gradleSourceSet, Object variant) { + private static void addTests( + DefaultGradleSourceSet gradleSourceSet, + Project project, + Object variant, + List sourceSets + ) { try { Object unitTestVariant = invokeMethod(variant, "getUnitTestVariant"); Object testVariant = invokeMethod(variant, "getTestVariant"); gradleSourceSet.setHasTests(unitTestVariant != null || testVariant != null); + + if (unitTestVariant != null) { + GradleSourceSet unitTestSourceSet = + convertVariantToGradleSourceSet(project, unitTestVariant, sourceSets, true); + if (unitTestSourceSet != null) { + sourceSets.add(unitTestSourceSet); + } + } + + if (testVariant != null) { + GradleSourceSet androidTestSourceSet = + convertVariantToGradleSourceSet(project, testVariant, sourceSets, false); + if (androidTestSourceSet != null) { + sourceSets.add(androidTestSourceSet); + } + } } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { // do nothing } @@ -393,7 +456,10 @@ private static void addTests(DefaultGradleSourceSet gradleSourceSet, Object vari * @param gradleSourceSet Instance of DefaultGradleSourceSet * @param compilerArgs List of compiler arguments needed to build the language extension. */ - private static void addExtensions(DefaultGradleSourceSet gradleSourceSet, List compilerArgs) { + private static void addExtensions( + DefaultGradleSourceSet gradleSourceSet, + List compilerArgs + ) { Map extensions = new HashMap<>(); boolean isJavaSupported = Arrays.stream(SourceSetUtils.getSupportedLanguages()) .anyMatch(l -> Objects.equals(l, SupportedLanguages.JAVA.getBspName())); diff --git a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java index 9e676335..ea99d4a5 100644 --- a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java +++ b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java @@ -100,18 +100,19 @@ void testAndroidSourceSets() { preferenceManager.setPreferences(new Preferences()); GradleApiConnector connector = new GradleApiConnector(preferenceManager); GradleSourceSets gradleSourceSets = connector.getGradleSourceSets(projectDir.toURI(), null); - assertEquals(4, gradleSourceSets.getGradleSourceSets().size()); + assertEquals(10, gradleSourceSets.getGradleSourceSets().size()); findSourceSet(gradleSourceSets, "app [debug]"); + findSourceSet(gradleSourceSets, "app [debugUnitTest]"); + findSourceSet(gradleSourceSets, "app [debugAndroidTest]"); findSourceSet(gradleSourceSets, "app [release]"); + findSourceSet(gradleSourceSets, "app [releaseUnitTest]"); findSourceSet(gradleSourceSets, "mylibrary [debug]"); + findSourceSet(gradleSourceSets, "mylibrary [debugUnitTest]"); + findSourceSet(gradleSourceSets, "mylibrary [debugAndroidTest]"); findSourceSet(gradleSourceSets, "mylibrary [release]"); + findSourceSet(gradleSourceSets, "mylibrary [releaseUnitTest]"); Set combinedModuleDependencies = new HashSet<>(); for (GradleSourceSet sourceSet : gradleSourceSets.getGradleSourceSets()) { - assertEquals(2, sourceSet.getSourceDirs().size()); - assertEquals(4, sourceSet.getResourceDirs().size()); - assertEquals(0, sourceSet.getExtensions().size()); - assertEquals(0, sourceSet.getArchiveOutputFiles().size()); - assertTrue(sourceSet.hasTests()); combinedModuleDependencies.addAll(sourceSet.getModuleDependencies()); } // This test can vary depending on the environment due to generated files. @@ -120,9 +121,7 @@ void testAndroidSourceSets() { // the R.jar files don't exist for the build targets and are not included. // 2. ANDROID_HOME is not configured in which case the Android Component classpath // is not added to module dependencies. - - // 57 is the number of actual project module dependencies without test variant dependencies - assertTrue(combinedModuleDependencies.size() >= 57); + assertTrue(combinedModuleDependencies.size() >= 82); } private GradleSourceSet findSourceSet(GradleSourceSets gradleSourceSets, String displayName) {