diff --git a/src/main/java/com/jfrog/ide/common/yarn/YarnTreeBuilder.java b/src/main/java/com/jfrog/ide/common/yarn/YarnTreeBuilder.java index f9b2ddc..74e2744 100644 --- a/src/main/java/com/jfrog/ide/common/yarn/YarnTreeBuilder.java +++ b/src/main/java/com/jfrog/ide/common/yarn/YarnTreeBuilder.java @@ -101,7 +101,7 @@ private void addDepTreeNodes(Map nodes, JsonNode jsonDep, D * @param rawDependency - The raw dependency Json string returned from 'Yarn why' command. * @return The extracted dependency path as a list of dependencies starting from projectRootId till packageFullName. */ - private List extractSinglePath(String projectRootId, String packageFullName, String rawDependency) { + List extractSinglePath(String projectRootId, String packageFullName, String rawDependency) { List pathResult = new ArrayList<>(); pathResult.add(projectRootId); // The root project is guaranteed to be the first element in the path @@ -135,7 +135,7 @@ private List extractSinglePath(String projectRootId, String packageFullN * @param rawDependencyPaths - The raw dependency Json strings returned from 'Yarn why' command. * @return The extracted dependency paths as a list of dependencies starting from projectRootId till packageFullName. */ - private List> extractMultiplePaths(String projectRootId, String packageFullName, List rawDependencyPaths) { + List> extractMultiplePaths(String projectRootId, String packageFullName, List rawDependencyPaths) { List> paths = new ArrayList<>(); int limit = rawDependencyPaths.size() < ImpactTree.IMPACT_PATHS_LIMIT ? rawDependencyPaths.size() : 50; for (int i = 0; i < limit; i++) { diff --git a/src/test/java/com/jfrog/ide/common/yarn/YarnTreeBuilderTest.java b/src/test/java/com/jfrog/ide/common/yarn/YarnTreeBuilderTest.java index a38c3f4..c490e08 100644 --- a/src/test/java/com/jfrog/ide/common/yarn/YarnTreeBuilderTest.java +++ b/src/test/java/com/jfrog/ide/common/yarn/YarnTreeBuilderTest.java @@ -16,6 +16,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.Set; import static org.testng.Assert.*; @@ -46,17 +49,8 @@ enum Project { @BeforeMethod public void setUp(Object[] testArgs) { - try { - tempProject = Files.createTempDirectory("ide-plugins-common-yarn").toFile(); - tempProject.deleteOnExit(); - FileUtils.copyDirectory(((Project) testArgs[0]).path.toFile(), tempProject); - Path projectDir = tempProject.toPath(); - descriptorFilePath = projectDir.resolve("package.json").toString(); - YarnTreeBuilder yarnTreeBuilder = new YarnTreeBuilder(projectDir, descriptorFilePath, null); - depTree = yarnTreeBuilder.buildTree(new NullLog()); - assertNotNull(depTree); - } catch (IOException e) { - fail(e.getMessage(), e); + if (!yarnDriver.isYarnInstalled()) { + throw new SkipException("Skip test, yarn is not installed."); } } @@ -74,10 +68,15 @@ private Object[][] yarnTreeBuilderProvider() { } @Test(dataProvider = "yarnTreeBuilderProvider") - public void yarnTreeBuilderTest(Project project, int expectedChildren) { - if (!yarnDriver.isYarnInstalled()) { - throw new SkipException("Skip test, yarn is not installed."); - } + public void yarnTreeBuilderTest(Project project, int expectedChildren) throws IOException { + tempProject = Files.createTempDirectory("ide-plugins-common-yarn").toFile(); + tempProject.deleteOnExit(); + FileUtils.copyDirectory((project).path.toFile(), tempProject); + Path projectDir = tempProject.toPath(); + descriptorFilePath = projectDir.resolve("package.json").toString(); + YarnTreeBuilder yarnTreeBuilder = new YarnTreeBuilder(projectDir, descriptorFilePath, null); + depTree = yarnTreeBuilder.buildTree(new NullLog()); + assertNotNull(depTree); String expectedProjectName = project.name; checkDependencyTree(expectedProjectName, expectedChildren); } @@ -117,4 +116,73 @@ private void fourChildrenScenario() { } assertEquals(count, 4); } + + @Test + public void extractSinglePathTest() { + String projectRootId = "root"; + String packageFullName = "pkg:1.0.0"; + String rawDependency = "{\"type\":\"info\",\"data\":\"This module exists because \\\"pkg#subpkg#dep\\\" depends on it.\"}"; + + YarnTreeBuilder yarnTreeBuilder = new YarnTreeBuilder(Paths.get(""), "", null); + List pathResult = yarnTreeBuilder.extractSinglePath(projectRootId, packageFullName, rawDependency); + + assertNotNull(pathResult); + assertEquals(pathResult.size(), 2); + assertEquals(pathResult.get(0), projectRootId); + assertEquals(pathResult.get(1), packageFullName); + } + + @Test + public void extractMultiplePathsTest() { + String projectRootId = "root"; + String packageFullName = "pkg:1.0.0"; + List rawDependencyPaths = List.of( + "{\"type\":\"reasons\",\"items\":[\"Specified in \\\"dependencies\\\"\",\"Hoisted from \\\"pkg#dep1\\\"\",\"Hoisted from \\\"pkg#dep2\\\"\"]}", + "{\"type\":\"reasons\",\"items\":[\"Specified in \\\"devDependencies\\\"\",\"Hoisted from \\\"pkg#dep3\\\"\"]}" + ); + + YarnTreeBuilder yarnTreeBuilder = new YarnTreeBuilder(Paths.get(""), "", null); + List> paths = yarnTreeBuilder.extractMultiplePaths(projectRootId, packageFullName, rawDependencyPaths); + + assertNotNull(paths); + assertEquals(paths.size(), 2); + assertEquals(paths.get(0).size(), 4); + assertEquals(paths.get(0).get(0), projectRootId); + assertEquals(paths.get(0).get(1), packageFullName); + assertEquals(paths.get(0).get(2), "pkg#dep1"); + assertEquals(paths.get(0).get(3), "pkg#dep2"); + + assertEquals(paths.get(1).size(), 3); + assertEquals(paths.get(1).get(0), projectRootId); + assertEquals(paths.get(1).get(1), packageFullName); + assertEquals(paths.get(1).get(2), "pkg#dep3"); + } + + @Test + public void findDependencyImpactPathsTest() throws IOException { + String projectRootId = "root"; + String packageName = "pkg"; + Set packageVersions = Set.of("1.0.0", "2.0.0"); + List yarnWhyOutput = List.of( + "{\"type\":\"info\",\"data\":\"Found \\\"pkg@1.0.0\\\"\"}", + "{\"type\":\"list\",\"data\":{\"type\":\"reasons\",\"items\":[\"Specified in \\\"dependencies\\\"\",\"Hoisted from \\\"pkg#dep1\\\"\",\"Hoisted from \\\"pkg#dep2\\\"\"]}}" + ); + + YarnTreeBuilder yarnTreeBuilder = new YarnTreeBuilder(Paths.get(""), "", null); + Map>> paths = yarnTreeBuilder.findDependencyImpactPaths(new NullLog(), projectRootId, packageName, packageVersions); + + assertNotNull(paths); + assertEquals(paths.size(), 1); + + List> pkgPaths = paths.get("pkg:1.0.0"); + assertNotNull(pkgPaths); + assertEquals(pkgPaths.size(), 1); + + List singlePath = pkgPaths.get(0); + assertEquals(singlePath.size(), 4); + assertEquals(singlePath.get(0), projectRootId); + assertEquals(singlePath.get(1), "pkg:1.0.0"); + assertEquals(singlePath.get(2), "pkg#dep1"); + assertEquals(singlePath.get(3), "pkg#dep2"); + } } \ No newline at end of file