DependencyTreeBuilder.kt

1
package com.depanalyzer.report
2
3
import com.depanalyzer.core.graph.DependencyNode
4
5
class DependencyTreeBuilder(
6
    private val vulnerabilities: Map<String, List<Vulnerability>> = emptyMap(),
7
    private val outdatedMap: Map<String, OutdatedDependency> = emptyMap()
8
) {
9
10
    fun buildTree(
11
        rootNodes: List<DependencyNode>,
12
        maxDepth: Int? = null,
13
        expandMode: TreeExpandMode = TreeExpandMode.ALL
14
    ): List<DependencyTreeNode> {
15 1 1. buildTree : replaced return value with Collections.emptyList for com/depanalyzer/report/DependencyTreeBuilder::buildTree → KILLED
        return rootNodes.mapNotNull { rootNode ->
16
            nodeToTreeNode(
17
                node = rootNode,
18
                isDirectDep = true,
19
                currentDepth = 0,
20
                maxDepth = maxDepth,
21
                expandMode = expandMode,
22
                chain = listOf(rootNode.coordinate)
23
            )
24
        }
25
    }
26
27
    private fun nodeToTreeNode(
28
        node: DependencyNode,
29
        isDirectDep: Boolean,
30
        currentDepth: Int,
31
        maxDepth: Int?,
32
        expandMode: TreeExpandMode,
33
        chain: List<String>
34
    ): DependencyTreeNode? {
35
        val coordinate = node.coordinate
36
37 1 1. nodeToTreeNode : negated conditional → KILLED
        val vulns = vulnerabilities[coordinate] ?: emptyList()
38
        val outdated = outdatedMap[coordinate]
39 1 1. nodeToTreeNode : negated conditional → KILLED
        val latestVersion = outdated?.latestVersion
40
41 3 1. nodeToTreeNode : negated conditional → KILLED
2. nodeToTreeNode : negated conditional → KILLED
3. nodeToTreeNode : negated conditional → KILLED
        val hasProblems = vulns.isNotEmpty() || latestVersion != null
42
43
        val children = mutableListOf<DependencyTreeNode>()
44
45 3 1. nodeToTreeNode : negated conditional → KILLED
2. nodeToTreeNode : negated conditional → KILLED
3. nodeToTreeNode : changed conditional boundary → KILLED
        if (maxDepth == null || currentDepth < maxDepth) {
46
            for (child in node.children) {
47
                val childTreeNode = nodeToTreeNode(
48
                    node = child,
49
                    isDirectDep = false,
50 1 1. nodeToTreeNode : Replaced integer addition with subtraction → KILLED
                    currentDepth = currentDepth + 1,
51
                    maxDepth = maxDepth,
52
                    expandMode = expandMode,
53
                    chain = chain + child.coordinate
54
                )
55 1 1. nodeToTreeNode : negated conditional → KILLED
                if (childTreeNode != null) {
56
                    children.add(childTreeNode)
57
                }
58
            }
59
        }
60
61
        val shouldInclude = when (expandMode) {
62
            TreeExpandMode.COLLAPSED -> {
63 2 1. nodeToTreeNode : negated conditional → NO_COVERAGE
2. nodeToTreeNode : negated conditional → NO_COVERAGE
                isDirectDep && hasProblems
64
            }
65
66
            TreeExpandMode.CRITICAL -> {
67 3 1. nodeToTreeNode : negated conditional → NO_COVERAGE
2. nodeToTreeNode : negated conditional → NO_COVERAGE
3. nodeToTreeNode : negated conditional → NO_COVERAGE
                hasProblems || children.isNotEmpty()
68
            }
69
70
            TreeExpandMode.HIGH -> {
71 3 1. nodeToTreeNode : negated conditional → NO_COVERAGE
2. nodeToTreeNode : negated conditional → NO_COVERAGE
3. nodeToTreeNode : negated conditional → NO_COVERAGE
                hasProblems || children.isNotEmpty()
72
            }
73
74
            TreeExpandMode.MEDIUM -> {
75 3 1. nodeToTreeNode : negated conditional → NO_COVERAGE
2. nodeToTreeNode : negated conditional → NO_COVERAGE
3. nodeToTreeNode : negated conditional → NO_COVERAGE
                hasProblems || children.isNotEmpty()
76
            }
77
78
            TreeExpandMode.ALL -> {
79 3 1. nodeToTreeNode : negated conditional → KILLED
2. nodeToTreeNode : negated conditional → KILLED
3. nodeToTreeNode : negated conditional → KILLED
                hasProblems || children.isNotEmpty()
80
            }
81
        }
82
83 1 1. nodeToTreeNode : negated conditional → KILLED
        if (!shouldInclude) {
84
            return null
85
        }
86
87 1 1. nodeToTreeNode : replaced return value with null for com/depanalyzer/report/DependencyTreeBuilder::nodeToTreeNode → KILLED
        return DependencyTreeNode(
88
            groupId = node.groupId,
89
            artifactId = node.artifactId,
90
            currentVersion = node.version,
91
            latestVersion = latestVersion,
92
            isDirectDependency = isDirectDep,
93
            isDependencyManagement = node.isDependencyManagement,
94
            scope = node.scope,
95
            vulnerabilities = vulns.sortedBy { it.severity.ordinal }.reversed(),
96
            children = children.sortByDependencyType(),
97 1 1. nodeToTreeNode : negated conditional → SURVIVED
            dependencyChain = if (isDirectDep) null else chain,
98
            ecosystem = node.ecosystem
99
        )
100
    }
101
102
    private fun List<DependencyTreeNode>.sortByDependencyType(): List<DependencyTreeNode> {
103 1 1. sortByDependencyType : replaced return value with Collections.emptyList for com/depanalyzer/report/DependencyTreeBuilder::sortByDependencyType → KILLED
        return this.sortedWith(compareBy<DependencyTreeNode> { node ->
104
            !node.hasOutdated
105
        }.thenBy { node ->
106
            -(node.maxSeverity?.ordinal ?: Int.MAX_VALUE)
107
        })
108
    }
109
}

Mutations

15

1.1
Location : buildTree
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
replaced return value with Collections.emptyList for com/depanalyzer/report/DependencyTreeBuilder::buildTree → KILLED

37

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

39

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

41

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

2.2
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:orders nodes with outdated versions first()]
negated conditional → KILLED

3.3
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

45

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

2.2
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

3.3
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
changed conditional boundary → KILLED

50

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
Replaced integer addition with subtraction → KILLED

55

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

63

1.1
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

67

1.1
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

71

1.1
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

75

1.1
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : nodeToTreeNode
Killed by : none
negated conditional → NO_COVERAGE

79

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

2.2
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

3.3
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

83

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

87

1.1
Location : nodeToTreeNode
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
replaced return value with null for com/depanalyzer/report/DependencyTreeBuilder::nodeToTreeNode → KILLED

97

1.1
Location : nodeToTreeNode
Killed by : none
negated conditional → SURVIVED
Covering tests

103

1.1
Location : sortByDependencyType
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
replaced return value with Collections.emptyList for com/depanalyzer/report/DependencyTreeBuilder::sortByDependencyType → KILLED

120

1.1
Location : buildTree
Killed by : com.depanalyzer.report.DependencyTreeBuilderTest.[engine:junit-jupiter]/[class:com.depanalyzer.report.DependencyTreeBuilderTest]/[method:respects tree depth limit()]
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1